0

내 응용 프로그램에 모달로 뷰 컨트롤러를 제공합니다. 사용자가 제스처로보기를 "쓸어 넘기"를 할 수 있기를 바랍니다. 이것은 UIGestureRecognizer에 매여있다애니메이션이 제대로 작동하지 않습니다.

- (void)handlePan:(UIPanGestureRecognizer *)recognizer { 
    CGFloat elasticThreshold = 100; 
    CGFloat dismissThreshold = 200; 
    CGPoint translation = [recognizer translationInView:self.view]; 
    CGFloat newY = 0; 
    CGFloat translationFactor = 0.5; 

    if (recognizer.state == UIGestureRecognizerStateEnded) { 
     if (translation.y < dismissThreshold) { 
      newY = 0; 
     } 
    } else { 
     if (translation.y > elasticThreshold) { 
      CGFloat frictionLength = translation.y - elasticThreshold; 
      CGFloat frictionTranslation = 30 * atan(frictionLength/120) + frictionLength/10; 
      newY = frictionTranslation + (elasticThreshold * translationFactor); 
     } else { 
      newY = translation.y*translationFactor; 
     } 
    } 

    if (translation.y > dismissThreshold) { 
     [UIView animateKeyframesWithDuration:0.5 delay:0.0 options:0 animations:^{ 
      [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{ 
       self.overlay.effect = nil; 
       self.collectionView.transform = CGAffineTransformMakeTranslation(0, self.view.frame.size.height); 
      }]; 
      [UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.1 animations:^{ 
       self.pageControl.frame = CGRectMake((self.view.frame.size.width-200)/2, self.view.frame.size.height, 200, 20); 
      }]; 
     } completion:^(BOOL finished) { 
      if (finished) { 
       [self dismissViewControllerAnimated:YES completion:nil]; 
      } 
     }]; 
    } else { 
     self.collectionView.transform = CGAffineTransformMakeTranslation(0, newY); 
     self.pageControl.transform = CGAffineTransformMakeTranslation(0, (newY+self.collectionView.frame.size.height)-20); 
    } 
} 

:

self.pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
self.pan.delegate = self; 
self.pan.maximumNumberOfTouches = 1; 
[self.view addGestureRecognizer:self.pan]; 

그러나, 무슨 일하면 완료 블록이 즉시 실행하는 것입니다 그 아래의 코드를 썼다. 그러면보기가 아래로 이동하고 (dismissViewControllerAnimated로 인해) 동시에 overlay.effect이 사라지는 것을 볼 수 있습니다. 그러나, 내가 원했던 것은 내 애니메이션이 발생하고 나서 View Controller가 자동으로 해제하는 것입니다.

어떤 아이디어가 잘못 되었습니까?

+0

제스처 처리의 나머지 부분은 어떻게됩니까? 제스처 상태가 변경되면보기가 이동합니까? 팬이 끝났을 때만 아무 것도하지 않는 것이 이상합니다. – jrturton

+0

팬이 끝나면 다시 0으로 이동합니다. 그렇지 않으면 나는보기를 아래로 움직이고있다. – user4992124

+0

하지만 그 코드는 질문에 없습니다 – jrturton

답변

0

중첩UIView 애니메이션 블록이기 때문에 발생합니다. 당신은이에 대한 dispatch_after을 사용해야 할 할 작업이없는 경우

double delayInSeconds = 0.5; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    [self dismissViewControllerAnimated:YES completion:nil]; 
}); 
+0

중첩되지 않습니까? 나는 단지'animateKeyframesWithDuration'에 keyframes를 추가한다. 그러나보기 컨트롤러의 해고를 연기하는 것이 효과적 일 수 있습니다. – user4992124

+0

@ user4992124 요점은 블록을 주 블록 내부에서 호출하고 완료 블록이 예상보다 빨리 실행되도록 트리거하는 것입니다. – the4kman

+0

여전히보기가 거의 즉시 해제됩니다. – user4992124

0

UIView의 키 프레임 (또는 표준) 애니메이션이 즉시 완료 블록을 실행합니다. 애니메이트 할 것이 없다면 애니메이션의 지속 시간을 기다리지 않습니다.

해제 애니메이션을 시작한 경우보기가 이미 최종 상태이므로 애니메이션이없고 완료 블록이 즉시 실행되는 것으로 보입니다.

관련 문제