Tyler
Tyler

Reputation: 2386

Disable swipe in UIPageViewController

I have a UIViewController with UIPageViewController variable.

I am trying to disable the swiping for the UIPageViewController for certain positions on screen. I am doing this by setting the UIViewController as a UIGestureRecognizerDelegate and setting the gesture recognizers in the UIPageViewController delegate to self (the UIViewController). I can't seem to find where the gesture recognizers are or get loaded for the UIPageViewController.

I've tried these three places and all come up empty in the viewDidLoad method:

println("gesture\(self.pageViewController!.gestureRecognizers)")
println("gesture\(self.view.gestureRecognizers)")
println("gesture\(self.pageViewController!.view.gestureRecognizers)")

UPDATE*******************:

so I found some UIGestureRecognizers hiding in the navigationController, but adding them as delegates and running the code below does nothing. Is it because I have the wrong UIGestureRecognizers. There is one in there that is a UIPanGestureRecognizer as well. Why don't I get any recognizers in my page controller or the view of my page controller?

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    println("Should recieve touch")
    return false
}

I am getting the "Should receive touch" to print to the logs but I return false and no swiping is disabled. What am I doing wrong?

Upvotes: 2

Views: 5634

Answers (4)

rajdurai
rajdurai

Reputation: 11

I had a case like a tableview inside a pageViewController and when swiping on a cell to bring up the option to delete. But the pageViewController gesture is only triggered.

So in order to maintain pagingView swipe, while allowing your content controls to use their features (Swipe to delete, etc), just turn off canCancelContentTouches in the UIPageViewController.

In your UIPageViewController's viewDidLoad

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

Upvotes: 0

Mohsen Fard
Mohsen Fard

Reputation: 598

You can use this extension for swift :

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

and call this:

pageCtrl.isPagingEnabled = false

Upvotes: 0

Lombas
Lombas

Reputation: 1132

You can get the UIPageViewController gesture Recognizer with :

UIPageViewController.view.subviews.first

In my test i get:

    - [0] : <UIScrollViewDelayedTouchesBeganGestureRecognizer: 0x17e57f20; state = Possible; delaysTouchesBegan = YES; view = <_UIQueuingScrollView 0x1842b800>; target= <(action=delayed:, target=<_UIQueuingScrollView 0x1842b800>)>>
- [1] : <UIScrollViewPanGestureRecognizer: 0x17e58470; state = Possible; delaysTouchesBegan = YES; delaysTouchesEnded = NO; view = <_UIQueuingScrollView 0x1842b800>; target= <(action=handlePan:, target=<_UIQueuingScrollView 0x1842b800>)>; must-fail = {
    <UIScrollViewPagingSwipeGestureRecognizer: 0x17d50110; state = Possible; view = <_UIQueuingScrollView 0x1842b800>; target= <(action=_handleSwipe:, target=<_UIQueuingScrollView 0x1842b800>)>>
}>
- [2] : <UIScrollViewPagingSwipeGestureRecognizer: 0x17d50110; state = Possible; view = <_UIQueuingScrollView 0x1842b800>; target= <(action=_handleSwipe:, target=<_UIQueuingScrollView 0x1842b800>)>; must-fail-for = {
    <UIScrollViewPanGestureRecognizer: 0x17e58470; state = Possible; delaysTouchesBegan = YES; delaysTouchesEnded = NO; view = <_UIQueuingScrollView 0x1842b800>; target= <(action=handlePan:, target=<_UIQueuingScrollView 0x1842b800>)>>
}>

Upvotes: 1

Romain TAILLANDIER
Romain TAILLANDIER

Reputation: 1985

By the past i have tried to do something similar with a UIScrollView. UIScrollView have member named panGesture. But you can loop on pageViewControllerGesture like this (tested on a standard Page-based application) :

 override func viewDidLoad() {
    super.viewDidLoad()

    // other set up

    // loop over your pageViewController gestures
    for gesture in self.pageViewController!.gestureRecognizers
    {
        // get the good one, i discover there are 2
        if(gesture is UIPanGestureRecognizer)
        {
            // replace delegate by yours (Do not forget to implement the gesture protocol)
            (gesture as! UIPanGestureRecognizer).delegate = self
        }
    }

}

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool
{
    // add custom logic
    var ShouldISwipe = rand()%2 == 0
    println("Should I Swipe : \(ShouldISwipe)")
    return ShouldISwipe
}

I have found that link that could help too (should be converted to swift) : http://www.lukaszielinski.de/blog/posts/2014/03/26/restrict-panning-of-uipageviewcontroller-to-certain-area/

Hope that could help.

Upvotes: 2

Related Questions