Disable UIPageViewController bounce

前端 未结 13 2382
离开以前
离开以前 2020-11-27 04:08

Searched a lot for this one, but couldn\'t find a proper solution yet.

Is it possible to disable the bounce effect of a UIPageViewController and still

相关标签:
13条回答
  • 2020-11-27 04:54

    Disable UIPageViewController's bounce

    1. Add the <UIScrollViewDelegate> delegate to your UIPageViewController's header

    2. Set the UIPageViewController's underlying UIScrollView's delegates to their parent in viewDidLoad:

      for (UIView *view in self.view.subviews) {
          if ([view isKindOfClass:[UIScrollView class]]) {
              ((UIScrollView *)view).delegate = self;
              break;
          }
      }
      
    3. The implementation for scrollViewDidScroll is to reset the contentOffset to the origin (NOT (0,0), but (bound.size.width, 0)) when the user is reaching out of the bounds, like this:

      - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
          if (_currentPage == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width) {
              scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
          } else if (_currentPage == totalViewControllersInPageController-1 && scrollView.contentOffset.x > scrollView.bounds.size.width) {
              scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
          }
      }
      
    4. Finally, the implementation for scrollViewWillEndDragging is to deal with a bug scenario when the user quickly swipes from left to right at the first page, the first page won't bounce at the left (due to the function above), but will bounce at the right caused by the (maybe) velocity of the swipe. And finally when bounced back, the UIPageViewController will trigger a page flip to the 2nd page (which is of course, not expected).

      - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
          if (_currentPage == 0 && scrollView.contentOffset.x <= scrollView.bounds.size.width) {
              *targetContentOffset = CGPointMake(scrollView.bounds.size.width, 0);
          } else if (_currentPage == totalViewControllersInPageController-1 && scrollView.contentOffset.x >= scrollView.bounds.size.width) {
              *targetContentOffset = CGPointMake(scrollView.bounds.size.width, 0);
          }
      }
      

    Swift 4.0

    Code to put into viewDidLoad:

    for subview in self.view.subviews {
        if let scrollView = subview as? UIScrollView {
            scrollView.delegate = self
            break;
        }
    }
    

    Implementation for scrollViewDidScroll:

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if (currentPage == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width) {
            scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0);
        } else if (currentPage == totalViewControllersInPageController - 1 && scrollView.contentOffset.x > scrollView.bounds.size.width) {
            scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0);
        }
    }
    

    Implementation for scrollViewWillEndDragging:

    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        if (currentPage == 0 && scrollView.contentOffset.x <= scrollView.bounds.size.width) {
            targetContentOffset.pointee = CGPoint(x: scrollView.bounds.size.width, y: 0);
        } else if (currentPage == totalViewControllersInPageController - 1 && scrollView.contentOffset.x >= scrollView.bounds.size.width) {
            targetContentOffset.pointee = CGPoint(x: scrollView.bounds.size.width, y: 0);
        }
    }
    
    0 讨论(0)
提交回复
热议问题