在调查 iOS 6 下 UIPageViewController 中的 Pan Gesture 问题时,我注意到它可以在一个手势内多次调用视图控制器方法之前/之后。这在我的特定情况下很糟糕,因为我需要等到动画完成后才能导航到下一页/上一页。因此,我们的方法具有这样的结构:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
if (animationInProgress)
return nil;
UIViewController *result = nil;
//do stuff to init result controller for next/prev page
if (result)
animationInProgress = YES;
return result;
}
方法相同viewControllerAfterViewController
。
动画结束后,调用 UIPageViewControllerDelegate 的这个方法:
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {
animationInProgress = NO;
//do other stuff to handle finishing animation.
}
由于 PanGesture 被多次调用,然后viewControllerAfterViewController
另一个方法因此被多次调用,不幸didFinishAnimating
的是在这种情况下没有调用方法,这导致animationInProgress
标志设置为YES
always 并且用户根本无法浏览页面。注意:仅在 iOS 6 中发生。
为了解决这个问题,我们必须以某种方式处理 PanGesture。使用 UIView gestureRecognizerShouldBegin:gestureRecognizer
(在 iOS 6 中添加)根本没有解决问题,当从 before/after 方法返回 nil 时,将控制器设置为手势的委托会导致崩溃。因此,我们尝试添加逻辑以在 PanGesture 处于UIGestureRecognizerStateChanged
状态的情况下不调用之前/之后的控制器方法(基于一些测试进行调查,以确定在循环调用方法时手势状态是什么)。
通过添加如下方法:
- (BOOL)skipIfPanGestureInProgress {
BOOL shouldSkip = NO;
if(pvcPanGestureRecognizer && [pvcPanGestureRecognizer state] == UIGestureRecognizerStateChanged){
animationInProgress = NO;
shouldSkip = YES;
}
return shouldSkip;
}
之后方法如下所示:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
if([self skipIfPanGestureInProgress]){
return nil;
}
if (animationInProgress)
return nil;
UIViewController *result = nil;
//do stuff to init result controller for next/prev page
if (result)
animationInProgress = YES;
return result;
}
这有助于解决 animationInProgress 标志的循环问题。
希望这对某人有帮助。