禁用UIPageViewController反弹

禁用UIPageViewController反弹

问题描述:

搜索了很多这个,但还没找到合适的解决方案。

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

是否可以禁用 UIPageViewController的反弹效果并仍然使用 UIPageViewControllerTransitionStyleScroll

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

禁用UIPageViewController的反弹



Disable UIPageViewController's bounce


  1. UIScrollViewDelegate> 委托给您的UIPageViewController的头
  1. Add the <UIScrollViewDelegate> delegate to your UIPageViewController's header

设置UIPageViewController的底层UIScrollView的

&LT添加代表他们的父母在 viewDidLoad

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;
    }
}


  • scrollViewDidScroll 是当用户超出界限时将contentOffset重置为原点( NOT(0,0),但是(bound.size.width,0)),如下所示:

    - (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);
        }
    }
    


  • 最后,执行 scrollViewWillEndDragging 用于处理错误情况,当用户在第一页从左向右快速滑动时,第一页不会在左侧反弹(由于上述功能),但会在右侧反弹由(可能)滑动速度引起的。反弹时,UIPageViewController会触发页面翻转到第2页(当然,这不是预期的)。

  • 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



    输入的代码viewDidLoad

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

    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);
        }
    }
    

    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);
        }
    }