문제

a 내부에 그래프가 그려져 있습니다 UIScrollView. 하나는 하나입니다 UIView 사용자 정의 서브 클래스 사용 CATiledLayer 층으로.

내가 확대 할 때 UIScrollView, 그래프가 그래프를 반환 할 때처럼 동적으로 크기를 조정하기를 원합니다. viewForZoomingInScrollView. 그러나 그래프는 새로운 줌 레벨에서 스스로를 다시 그리며 변환 스케일을 1x1로 재설정하여 다음에 사용자가 확대 할 때 변환이 현재보기에서 시작되도록합니다. 변환을 신원으로 재설정하면 scrollViewDidEndZooming, 그것은 시뮬레이터에서 작동하지만 EXC_BAD_ACCSES 장치에서.

다음에 사용자가 확대 할 때 변환이 줌 레벨에 어떤 줌 레벨이든지 재설정되기 때문에 이것은 시뮬레이터에 전적으로 문제를 해결하지 못합니다. 예를 들어 2x로 확대 된 경우처럼 보입니다. 갑자기 4 배입니다. 줌을 마치면 올바른 척도로 끝나지 만 실제 확대 / 축소 행위는 나빠 보입니다.

먼저 : 축소 후 1x1의 표준 스케일로 그래프가 다시 그리기를 허용하고 전체적으로 부드러운 줌을 어떻게합니까?

편집하다: 새로운 결과 오류는 "[CALayer retainCount]: message sent to deallocated instance"

나는 결코 층을 직접 처리하지 않습니다. 전에는 조회수 나 아무것도 삭제하지도 않았습니다. 이 오류는 줌과 회전 중에도 던져졌습니다. 회전하기 전에 객체를 삭제하고 나중에 다시 접수하면 예외가 발생하지 않습니다. 이것은 확대 / 축소 옵션이 아닙니다.

도움이 되었습니까?

해결책

나는 당신에게 당신에게 당신에게 당신에게 당신에게 당신에게 당신에게 당신이 당신의 코드 내 어딘가에도 뷰 나 계층을 자동으로 자동 표시하지 않는지 확인하는 것 외에는 충돌을 도울 수 없습니다. 시뮬레이터가 장치와의 자동 표시 타이밍을 다르게 처리하는 것을 보았습니다 (대부분 스레드가 관련 될 때).

보기 스케일링은 문제입니다 UIScrollView 그래도 나는 만난다. 핀치 Zooming 이벤트 중에 UIScrollView 당신이 지정한 견해를 취할 것입니다 viewForZoomingInScrollView: 방법을 위임하고 변환을 적용하십시오. 이 변환은 각 프레임을 다시 그리지 않고도 뷰의 부드러운 스케일링을 제공합니다. 줌 작동이 끝나면 대의원 방법 scrollViewDidEndZooming:withView:atScale: 새로운 스케일 요인에서 귀하의 견해를보다 고품질 렌더링 할 수있는 기회를 제공합니다. 일반적으로, 당신은 당신의 견해에 대한 변환을 CGAffineTransformIdentity 그런 다음 새 크기 규모로 수동으로 자신을 다시 그리기하십시오.

그러나 이것은 문제가 발생합니다 UIScrollView 컨텐츠보기 변환을 모니터링하는 것처럼 보이지 않으므로 다음 줌 작업에서는 전체 스케일 계수가 무엇이든 컨텐츠보기의 변환을 설정합니다. 마지막 스케일 팩터에서 수동으로 뷰를 다시 작성 했으므로 스케일링을 합성합니다. 이것이 바로보고있는 것입니다.

해결 방법으로 다음 방법이 정의 된 내용보기에 UIView 서브 클래스를 사용합니다.

- (void)setTransformWithoutScaling:(CGAffineTransform)newTransform;
{
    [super setTransform:newTransform];
}

- (void)setTransform:(CGAffineTransform)newValue;
{
    [super setTransform:CGAffineTransformScale(newValue, 1.0f / previousScale, 1.0f / previousScale)];
}

여기서 Pretcscale은 뷰의 플로트 인스턴스 변수입니다. 그런 다음 Zooming Delegate 메소드를 다음과 같이 구현합니다.

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;
{
    [contentView setTransformWithoutScaling:CGAffineTransformIdentity];
// Code to manually redraw view at new scale here
    contentView.previousScale = scale;
    scrollView.contentSize = contentView.frame.size;
}

이를 통해 컨텐츠보기로 전송 된 변환은보기가 마지막으로 다시 그려진 스케일에 따라 조정됩니다. 핀치 Zooming이 완료되면 변환은 정상의 조정을 우회하여 1.0의 스케일로 재설정됩니다. setTransform: 방법. 이것은 올바른 스케일링 동작을 제공하면서 줌을 완성 할 때 선명한 시야를 그릴 수있는 것 같습니다.

업데이트 (7/23/2010) : iPhone OS 3.2 이상은 축소와 관련하여 스크롤보기의 동작을 변경했습니다. 이제, a UIScrollView 컨텐츠보기에 적용되는 ID 변환을 존중하고 상대 척도 요소 만 제공합니다. -scrollViewDidEndZooming:withView:atScale:. 따라서 위의 코드는 a UIView 서브 클래스는 3.2보다 오래된 iPhone OS 버전을 실행하는 장치에만 필요합니다.

다른 팁

모든 이전 답변 덕분에 여기에 내 해결책이 있습니다.
구현하다 uiscrollviewdelegate 행동 양식:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return tmv;
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
    CGPoint contentOffset = [tmvScrollView contentOffset];   
    CGSize  contentSize   = [tmvScrollView contentSize];
     CGSize  containerSize = [tmv frame].size;

    tmvScrollView.maximumZoomScale = tmvScrollView.maximumZoomScale / scale;
    tmvScrollView.minimumZoomScale = tmvScrollView.minimumZoomScale / scale;

    previousScale *= scale;

    [tmvScrollView setZoomScale:1.0f];

    [tmvScrollView setContentOffset:contentOffset];
    [tmvScrollView setContentSize:contentSize];
    [tmv setFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)];  

    [tmv reloadData];
}
  • TMV Uiview의 서브 클래스입니다
  • tmvscrollview - UiscrollView의 아울렛
  • 세트 최대 zoomscale 그리고 최소 zoomscale ~ 전에
  • 만들다 PERPSCALE 인스턴스 변수 및 값을 1.0F로 설정합니다

나를 위해 완벽하게 작동합니다.

BR, 유진.

축소 할 때 ScrollView는 다음 번에 거래가 될 때까지 동일한 줌 스케일을 갖기 때문에로드에서 기본 줌 스케일로 재설정하려고했습니다.

-(void) viewWillAppear:(BOOL)animated {
      [self.scrollView setZoomScale:1.0f];
}

게임을 변경했습니다.

UiscrollView Zooming이 어떻게 작동하는지에 대한 자세한 토론이 있습니다. github.com/andreyvit/scrollingmadness/.

(링크에는 프로그래밍 방식으로 Uiscrollview를 프로그래밍 방식으로 확대하는 방법, 사진 라이브러리 스타일 페이징+Zooming+Scrolling, 예제 프로젝트 및 ZoomscrollView 클래스를 줌 줌 마술을 캡슐화하는 방법에 대한 설명이 포함되어 있습니다).

인용하다:

Uiscrollview는 "현재 줌 레벨"이라는 개념이 없습니다. 포함하는 각 하위 뷰에는 자체 줌 레벨이있을 수 있기 때문입니다. UiscrollView에는 현재 줌 레벨을 유지하기위한 필드가 없습니다. 그러나 우리는 누군가가 줌 레벨을 저장한다는 것을 알고 있습니다. 왜냐하면 당신이 하위 뷰를 핀치하고 cgaffinetransformidentity로 변환을 재설정 한 다음 다시 꼬집기 때문에 하위 뷰의 이전 줌 레벨이 복원되었음을 알 수 있습니다.

실제로, 분해를 보면, 자체 줌 레벨을 저장하는 것은 uiview입니다 (_gestureInfo 필드가 가리키는 uigestureInfo 객체 내부). 또한 문서화되지 않은 멋진 메소드도 있습니다. zoomScale 그리고 setZoomScale:animated:. (당신에게도, 그것은 또한 많은 회전 관련 방법을 가지고 있습니다. 아마도 우리는 곧 회전 제스처 지원을 받고있을 것입니다.)

그러나 확대 / 축소를위한 새로운 UIView를 만들고 실제 확대 실용보기를 자식으로 추가하면 항상 줌 레벨 1.0으로 시작합니다. 프로그래밍 방식 축소의 구현은이 트릭을 기반으로합니다.

iOS 3.2 및 4.0 이상에 적합한 상당히 신뢰할 수있는 접근 방식은 다음과 같습니다. 요청 된 척도로 확장 가능한보기 (스크롤보기의 주요 하위 뷰)를 제공 할 준비가되어 있어야합니다. 그런 다음 scrollViewDidEndZooming: 이보기의 흐릿한 스케일 변형 버전을 제거하고 새로운 뷰로 새로운 뷰로 바꾸는 버전을 제거합니다.

필요할 것이예요:

  • 이전 척도를 유지하기위한 IVAR; 그것을 구식이라고 부릅니다

  • 확장 가능한 견해를 식별하는 방법, 둘 다 viewForZoomingInScrollView: 그리고 scrollViewDidEndZooming:; 여기, 나는 태그를 적용 할 것입니다 (999)

  • 확장 가능한보기를 생성하고 태그를 붙이고 스크롤보기에 삽입하는 메소드 (여기서는 호출 할 것입니다. addNewScalableViewAtScale:). 규모에 따라 모든 작업을 수행해야합니다. 뷰와 하위 뷰 또는 드로잉 크기, 스크롤보기의 내용이 일치하도록 크기를 크기를냅니다.

  • 최소 zoomscale 및 최대 ZoomScale의 상수. 세부적인 더 큰 버전으로 스케일 된보기를 교체 할 때 시스템은 현재 스케일이 1이라고 생각할 것이므로 사용자가 뷰를 다시 아래로 축소 할 수 있도록하기 때문에 시스템이 필요하기 때문입니다.

그때 아주 잘. 스크롤보기를 만들 때 스케일 가능보기를 스케일 1.0으로 삽입합니다. 이것은 당신에있을 수 있습니다 viewDidLoad, 예를 들어 (sv 스크롤보기) :

[self addNewScalableViewAtScale: 1.0];
sv.minimumZoomScale = MIN;
sv.maximumZoomScale = MAX;
self->oldScale = 1.0;
sv.delegate = self;

그럼 당신의 scrollViewDidEndZooming: 당신은 똑같은 일을하지만 규모의 변화를 보상합니다.

UIView* v = [sv viewWithTag:999];
[v removeFromSuperview];
CGFloat newscale = scale * self->oldScale;
self->oldScale = newscale;
[self addNewScalableViewAtScale:newscale];
sv.minimumZoomScale = MIN / newscale;
sv.maximumZoomScale = MAX / newscale;

Brad가 제공하는 솔루션에는 한 가지 문제가 있습니다. 프로그래밍 방식으로 확대하는 경우 (더블 탭 이벤트에서는 예상하자), 실제 규모와 스케일의 차이를 수동으로 (핀치 아웃) 확대하는 경우. Uiscrollview가 추적 중입니다. previousScale 어느 시점에서 플로트의 정밀도에서 떨어지면 결국 예측할 수없는 행동이 발생합니다.

SWIFT 4.* 그리고 Xcode 9.3

ScrollView Zoom Scale을 0으로 설정하면 ScrollView가 초기 상태로 재설정됩니다.

self.scrollView.setZoomScale(0.0, animated: true)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top