如何禁用UIPageViewController的滑动手势?

问题描述 投票:108回答:15

在我的情况下,父母UIViewController包含UIPageViewController,其中包含含有UINavigationControllerUIViewController。我需要向最后一个视图控制器添加滑动手势,但滑动处理就像它们属于页面视图控制器一样。我尝试以编程方式和通过xib执行此操作,但没有结果。

据我所知,在UIPageViewController处理其手势之前,我无法达到目标。如何解决这个问题?

ios uiviewcontroller uigesturerecognizer uipageviewcontroller
15个回答
227
投票

记录的防止UIPageViewController滚动的方法是不分配dataSource属性。如果您分配数据源,它将进入“基于手势”的导航模式,这是您要阻止的。

如果没有数据源,您可以使用setViewControllers:direction:animated:completion方法手动提供视图控制器,并且它将根据需要在视图控制器之间移动。

以上可以从Apple's documentation of UIPageViewController(概述,第二段)推断:

要支持基于手势的导航,必须使用数据源对象提供视图控制器。


1
投票

类似于@ user3568340的答案

斯威夫特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
        }
    }

0
投票

翻译@ user2159978对C#的回复:

foreach (var view in pageViewController.View.Subviews){
   var subView = view as UIScrollView;
   if (subView != null){
     subView.ScrollEnabled = enabled;
   }
}

0
投票

感谢@ user2159978的回答。

我让它更容易理解。

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

0
投票

(Swift 4)您可以删除pageViewController的gestureRecognizers:

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

如果您更喜欢扩展名:

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

pageViewController.removeGestureRecognizers


0
投票

声明如下:

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

然后像这样使用它:

scrollView?.isScrollEnabled = true //false

0
投票

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

79
投票
for (UIScrollView *view in self.pageViewController.view.subviews) {

    if ([view isKindOfClass:[UIScrollView class]]) {

        view.scrollEnabled = NO;
    }
}

46
投票

我将user2159978的答案翻译成Swift

func removeSwipeGesture(){
    for view in self.pageViewController!.view.subviews {
        if let subView = view as? UIScrollView {
            subView.scrollEnabled = false
        }
    }
}

23
投票

实施@lee(@ user2159978)解决方案作为扩展:

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

用法:(在UIPageViewController

self.isPagingEnabled = false

9
投票

编辑:此答案仅适用于页面卷曲样式。 Jessedc's answer要好得多:无论风格如何都有效,并且依赖于记录在案的行为。

UIPageViewController公开了它的手势识别器数组,您可以使用它来禁用它们:

// myPageViewController is your UIPageViewController instance
for (UIGestureRecognizer *recognizer in myPageViewController.gestureRecognizers) {
    recognizer.enabled = NO;
}

8
投票

我已经打了一段时间了,我认为我应该发布我的解决方案,继耶塞德克的回答之后;删除PageViewController数据源。

我将它添加到我的PgeViewController类(链接到故事板中的页面视图控制器,继承UIPageViewControllerUIPageViewControllerDataSource):

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

然后可以在每个子视图出现时调用它(在这种情况下禁用它);

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

我希望这可以帮助别人,它不像我想的那样干净,但不会觉得太hacky等。

编辑:如果有人想将其翻译成Objective-C请做:)


5
投票

UIPageViewController的有用扩展,用于启用和禁用滑动。

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

4
投票

如果你想让你的UIPageViewController保持它的滑动能力,同时允许你的内容控件使用他们的功能(滑动删除等),只需关闭canCancelContentTouches中的UIPageViewController

把它放在你的UIPageViewControllerviewDidLoad功能中。 (迅速)

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

UIPageViewController有一个自动生成的子视图,用于处理手势。我们可以阻止这些子视图取消内容手势。

从...

Swipe to delete on a tableView that is inside a pageViewController


2
投票

我解决了这个问题(Swift 4.1)

if let scrollView = self.view.subviews.filter({$0.isKind(of: UIScrollView.self)}).first as? UIScrollView {
             scrollView.isScrollEnabled = false
}
© www.soinside.com 2019 - 2024. All rights reserved.