UIPageViewController实现小说阅读器遇到的bug及解决方案
上下滑动引起页面重复的bug
开始时的思路:修改UIPageViewController的UIPanGestureRecognizer手势
以下方案引发了以下bug
The number of view controllers provided (0) doesn’t match the number required (2) for the requested transition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| 解决方案开始思路:修改UIPageViewController的UIPanGestureRecognizer手势
//1 修改UIPageViewController的UIPanGestureRecognizer手势代理 for (UIGestureRecognizer *gr in _pageViewController.gestureRecognizers) { if ([gr isKindOfClass:[UIPanGestureRecognizer class]]) { gr.delegate = self; } }
//实现代理方法 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { //可如下方式过滤手势 // if ([touch.view isDescendantOfView:self.topView] || // [touch.view isDescendantOfView:self.bottomView] || // [touch.view isDescendantOfView:self.settingView] ) { // return NO; // } if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { UIPanGestureRecognizer *swipe = (UIPanGestureRecognizer *)gestureRecognizer; if (gestureRecognizer.state == UIGestureRecognizerStateChanged) { return [self commitTranslation:[swipe translationInView:self.view]]; } } return YES; }
//判断滑动方向 - (BOOL)commitTranslation:(CGPoint)translation { CGFloat absX = fabs(translation.x); CGFloat absY = fabs(translation.y); // 设置滑动有效距离 if (MAX(absX, absY) < 20) return NO; if (absX > absY ) { if (translation.x < 0) { //向左滑动 }else{ //向右滑动 } return YES; } else if (absY > absX) { if (translation.y<0) { //向上滑动 }else{ //向下滑动 } return NO; } return YES; }
|
解决方案二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { //此处会修正为正确的index NSUInteger index = [self indexOfViewController:(ContentViewController *)viewController]; if (index == NSNotFound) { return nil; } index++; if (index == [self.pageContentArray count]) { return nil; } return [self viewControllerAtIndex:index]; }
- (NSUInteger)indexOfViewController:(ContentViewController *)viewController { return [self.pageContentArray indexOfObject:viewController.content]; }
|
快速滑动 及其 滑动未完成又返回引起的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #pragma mark - UIPageViewControllerDataSource //显示前一页 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { if (self.transiting) { return nil; } return vc; }
//显示下一页 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { if (self.transiting) { return nil; } return vc; }
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers { //防止快速滑动引起的问题 self.transiting = YES; }
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed { self.transiting = NO; if (!completed) { 修改页面索引为未完成时的索引 } }
|