How to disable gesture swipe UIPageViewController?

In my case, the parent UIViewController contains a UIPageViewController which contains a UINavigationController which contains a UIViewController . I need to add a swipe gesture to the last view controller, but the swipe is handled as if it belonged to a pageview controller. I tried to do this both programmatically and through XIB, but to no avail.

Therefore, as I understand it, I will not be able to achieve my goal until the UIPageViewController has UIPageViewController gesturing it. How to solve this problem?

+113
ios uiviewcontroller uigesturerecognizer uipageviewcontroller
Feb 28 '14 at 14:55
source share
16 answers

A documented way to prevent scrolling of a UIPageViewController is to not dataSource property. If you assign a data source, it will go into the gesture-based navigation mode you are trying to prevent.

Without a data source, you manually provide view controllers when you want to use the setViewControllers:direction:animated:completion method, and it will move between view controllers on demand.

The above can be done from the Apple UIPageViewController documentation (overview, second paragraph):

To support gesture-based navigation, you must provide your view controllers using a data source object.

+235
Jul 20 '14 at 5:30
source share
 for (UIScrollView *view in self.pageViewController.view.subviews) { if ([view isKindOfClass:[UIScrollView class]]) { view.scrollEnabled = NO; } } 
+81
Mar 03 '14 at 9:56
source share

I will move user2159978's answer to Swift

 func removeSwipeGesture(){ for view in self.pageViewController!.view.subviews { if let subView = view as? UIScrollView { subView.scrollEnabled = false } } } 
+47
Jul 17 '15 at 7:56
source share

Implementing @lee solution (@ user2159978) as an extension:

 extension UIPageViewController { var isPagingEnabled: Bool { get { var isEnabled: Bool = true for view in view.subviews { if let subView = view as? UIScrollView { isEnabled = subView.isScrollEnabled } } return isEnabled } set { for view in view.subviews { if let subView = view as? UIScrollView { subView.isScrollEnabled = newValue } } } } } 

Usage: (in UIPageViewController )

 self.isPagingEnabled = false 
+24
Nov 02 '17 at 12:25
source share

Edit : this answer only works for page curl style. Jessc answer is much better: it works regardless of style and relies on documented behavior.

UIPageViewController expands its array of gesture recognizers, which you can use to disable them:

 // myPageViewController is your UIPageViewController instance for (UIGestureRecognizer *recognizer in myPageViewController.gestureRecognizers) { recognizer.enabled = NO; } 
+9
Feb 28 '14 at 14:59
source share

I struggled with this for a while and thought I should post my solution, following from Jessc's answer; Removing the PageViewController data source.

I added this to my PgeViewController class (associated with my storyboard page view controller in a storyboard, it inherits both UIPageViewController and UIPageViewControllerDataSource ):

 static func enable(enable: Bool){ let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate let pageViewController = appDelegate.window!.rootViewController as! PgeViewController if (enable){ pageViewController.dataSource = pageViewController }else{ pageViewController.dataSource = nil } } 

This can be caused when everyone appears under the view (in this case, turn it off);

 override func viewDidAppear(animated: Bool) { PgeViewController.enable(false) } 

I hope this helps someone, but not as cleanly as we would like, but not too cool, etc.

EDIT: if anyone wants to translate this into Objective-C, please :)

+8
Sep 10 '15 at 9:38
source share

If you want your UIPageViewController support scrolling, allowing your content controls to use their functions (swipe to delete, etc.), just turn off canCancelContentTouches in the UIPageViewController .

Put this in your UIPageViewController viewDidLoad functionality. (Swift)

 if let myView = view?.subviews.first as? UIScrollView { myView.canCancelContentTouches = false } 

UIPageViewController has an auto- UIPageViewController subquery that handles gestures. We can prevent these subzones from canceling content gestures.

FROM...

Swipe the screen in the View table, which is inside the pageViewController

+5
Aug 12 '16 at 22:30
source share

Useful UIPageViewController extension to enable or disable scrolling.

 extension UIPageViewController { func enableSwipeGesture() { for view in self.view.subviews { if let subView = view as? UIScrollView { subView.isScrollEnabled = true } } } func disableSwipeGesture() { for view in self.view.subviews { if let subView = view as? UIScrollView { subView.isScrollEnabled = false } } } } 
+5
Apr 23 '18 at 13:34
source share

I solved it like this (Swift 4.1)

 if let scrollView = self.view.subviews.filter({$0.isKind(of: UIScrollView.self)}).first as? UIScrollView { scrollView.isScrollEnabled = false } 
+2
May 05 '18 at 15:12
source share

Looks like @ user3568340 answer

Swift 4

 private var _enabled = true public var enabled:Bool { set { if _enabled != newValue { _enabled = newValue if _enabled { dataSource = self } else{ dataSource = nil } } } get { return _enabled } } 
+1
Jan 15 '18 at 14:06
source share

Fast answer method @lee

 extension UIPageViewController { var isPagingEnabled: Bool { get { return scrollView?.isScrollEnabled ?? false } set { scrollView?.isScrollEnabled = newValue } } var scrollView: UIScrollView? { return view.subviews.first(where: { $0 is UIScrollView }) as? UIScrollView } } 
+1
Mar 19 '19 at 10:25
source share

Translation of @ user2159978 response in C #:

 foreach (var view in pageViewController.View.Subviews){ var subView = view as UIScrollView; if (subView != null){ subView.ScrollEnabled = enabled; } } 
0
Feb 28 '18 at 22:58
source share

Thanks @ user2159978 answer.

I make it a little more understandable.

 - (void)disableScroll{ for (UIView *view in self.pageViewController.view.subviews) { if ([view isKindOfClass:[UIScrollView class]]) { UIScrollView * aView = (UIScrollView *)view; aView.scrollEnabled = NO; } } } 
0
Apr 04
source share

(Swift 4) You can remove the gesture recognizer of your ViewController page:

 pageViewController.view.gestureRecognizers?.forEach({ (gesture) in pageViewController.view.removeGestureRecognizer(gesture) }) 

If you prefer in the extension:

 extension UIViewController{ func removeGestureRecognizers(){ view.gestureRecognizers?.forEach({ (gesture) in view.removeGestureRecognizer(gesture) }) } } 

and pageViewController.removeGestureRecognizers

0
Jun 11 '18 at 9:33
source share

Declare it like this:

 private var scrollView: UIScrollView? { return pageViewController.view.subviews.compactMap { $0 as? UIScrollView }.first } 

Then use it like this:

 scrollView?.isScrollEnabled = true //false 
0
Mar 04 '19 at 17:54
source share

already set response pageViewController.view.isUserInteractionEnabled = false

0
Jul 09 '19 at 11:46
source share



All Articles