10

I am using a UIPageViewController with transitionStyle UIPageViewControllerTransitionStyleScroll and navigationOrientation UIPageViewControllerNavigationOrientationVertical

I also have a UIPanGestureRecognizer on the view and I want to disable page scrolling when the pan gesture is active.

I am trying to set the following when the gesture begins:

pageViewController.view.userInteractionEnabled = NO;

This seems to have no effect, or it appears to work sporadically.

The only other way I have found to do it (which works) is to set the UIPageViewController dataSource to nil while the pan gesture is running, however this causes a huge delay when resetting the dataSource.

simon
  • 2,635
  • 4
  • 20
  • 21

5 Answers5

22

UIPageViewController uses some UIScrollView object to handle scrolling (at least for transitionStyle UIPageViewControllerTransitionStyleScroll). You can iterate by controller's subviews pageViewController.view.subviews to get it. Now, you can easly enable/disable scrolling:

- (void)setScrollEnabled:(BOOL)enabled forPageViewController:(UIPageViewController*)pageViewController
{
    for (UIView *view in pageViewController.view.subviews) {
        if ([view isKindOfClass:UIScrollView.class]) {
            UIScrollView *scrollView = (UIScrollView *)view;
            [scrollView setScrollEnabled:enabled];
            return;
        }
    }
}
sig
  • 6,024
  • 2
  • 26
  • 31
squikend
  • 269
  • 2
  • 7
  • I've been searching for a while and this is the best answer i've found for disabling swiping on UIPageViewController but keeping the tap movement. – William Robinson May 07 '14 at 14:29
  • In swift, if you like condensed stuff a bit hard to read: `pageViewController.view.subviews.flatMap({ $0 as? UIScrollView}).forEach({$0.isScrollEnabled = enabled})` – HHK Oct 13 '16 at 01:56
3

For those who are using swift instead of objective-c, here is Squikend's solution transposed.

func findScrollView(#enabled : Bool) {
    for view in self.view.subviews {
      if view is UIScrollView {
        let scrollView = view as UIScrollView
        scrollView.scrollEnabled = enabled;
      } else {
        println("UIScrollView does not exist on this View")
      }

    }
  }
0

Everyone is complicating this very very much.

This is the whole function you need to disable or enable the scroll.

    func enableScroll(_ enable: Bool) {
        dataSource = enable ? self : nil
    }
Programmer
  • 134
  • 1
  • 12
-1

Swift 4.2 Version of the answer

func findScrollView(enabled: Bool) {
    for view in self.view.subviews {
        if view is UIScrollView {
            let scrollView = view as! UIScrollView
            scrollView.isScrollEnabled = enabled
        } else {
            print("UIScrollView does not exist on this View")
        }

    }
}

then yourpagecontorller.findScrollView(enabled: false)

cvb
  • 1,715
  • 18
  • 22
-2

You may also disable gesture recognizers.

for (UIGestureRecognizer *recognizer in pageViewController.gestureRecognizers)
{
    recognizer.enabled = NO;
}

Unlike the popular answer, which relies on existing of the inner UIScrollView, this one uses public gestureRecognizers array. The underlying scroll view may not exist if you use book-style paging.

kelin
  • 11,323
  • 6
  • 67
  • 104