在 UIPageViewController 中禁用滑动

Disable swipe in UIPageViewController

我有一个 UIViewControllerUIPageViewController 变量。

我正在尝试禁用 UIPageViewController 在屏幕上某些位置的滑动。为此,我将 UIViewController 设置为 UIGestureRecognizerDelegate,并将 UIPageViewController 委托中的手势识别器设置为自身(UIViewController)。我似乎无法找到手势识别器的位置或为 UIPageViewController 加载。

我已经尝试了这三个地方,但在 viewDidLoad 方法中都是空的:

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

更新*********************:

所以我发现一些 UIGestureRecognizers 隐藏在 navigationController 中,但是将它们添加为委托并且 运行 下面的代码没有任何作用。是不是因为我有错误的 UIGestureRecognizers。那里还有一个 UIPanGestureRecognizer。为什么我的页面控制器或页面控制器的视图中没有任何识别器?

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

我正在让 "Should receive touch" 打印到日志,但我 return 为 false,并且没有禁用滑动。我做错了什么?

过去我曾尝试用 UIScrollView 做类似的事情。 UIScrollView 有一个名为 panGesture 的成员。但是你可以像这样在 pageViewControllerGesture 上循环(在标准的基于页面的应用程序上测试过):

 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
}

我发现 link 也有帮助(应转换为 swift): http://www.lukaszielinski.de/blog/posts/2014/03/26/restrict-panning-of-uipageviewcontroller-to-certain-area/

希望对您有所帮助。

您可以通过以下方式获取 UIPageViewController 手势识别器:

UIPageViewController.view.subviews.first

在我的测试中我得到:

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

您可以将此扩展名用于 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
                }
            }
        }
    }
}

并调用这个:

pageCtrl.isPagingEnabled = false

我有一个类似 pageViewController 内的 tableview 的情况,当在单元格上滑动以显示删除选项时。但是pageViewController手势只是被触发了。

因此,为了保持 pagingView 滑动,同时允许您的内容控件使用它们的功能(滑动以删除等),只需关闭 UIPageViewController 中的 canCancelContentTouches。

在你的 UIPageViewController 的 viewDidLoad 中

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