ios 如何禁用 UIPageViewController 的滑动手势?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22098493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:36:59  来源:igfitidea点击:

How do I Disable the swipe gesture of UIPageViewController?

iosuiviewcontrolleruigesturerecognizeruipageviewcontroller

提问by user2159978

In my case parent UIViewControllercontains UIPageViewControllerwhich contains UINavigationControllerwhich contains UIViewController. I need to add a swipe gesture to the last view controller, but swipes are handled as if they belong to page view controller. I tried to do this both programmatically and via xib but with no result.

在我的情况下, parent UIViewControllercontains UIPageViewControllerwhich contains UINavigationControllerwhich contains UIViewController. 我需要向最后一个视图控制器添加一个滑动手势,但是滑动的处理就像它们属于页面视图控制器一样。我尝试以编程方式和通过 xib 执行此操作,但没有结果。

So as I understand I can't achieve my goal until UIPageViewControllerhandles its gestures. How to solve this issue?

因此,据我所知,除非UIPageViewController处理好它的手势,否则我无法实现我的目标。如何解决这个问题?

回答by Jessedc

The documented way to prevent the UIPageViewControllerfrom scrolling is to not assign the dataSourceproperty. If you assign the data source it will move into 'gesture-based' navigation mode which is what you're trying to prevent.

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

Without a data source you manually provide view controllers when you want to with setViewControllers:direction:animated:completionmethod and it will move between view controllers on demand.

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

The above can be deduced from Apple's documentation of UIPageViewController(Overview, second paragraph):

以上可以从苹果的 UIPageViewController 文档中推导出来(概述,第二段):

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

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

回答by user2159978

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

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

        view.scrollEnabled = NO;
    }
}

回答by lee

I translate answer of user2159978to Swift 5.1

我将user2159978 的答案翻译成Swift 5.1

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

回答by LinusGeffarth

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

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

Usage: (in UIPageViewController)

用法:(在UIPageViewController

self.isPagingEnabled = false

回答by Jamie Robinson

I've been fighting this for a while now and thought I should post my solution, following on from Jessedc's answer; removing the PageViewController's datasource.

我已经为此奋斗了一段时间,并认为我应该按照 Jessedc 的回答发布我的解决方案;删除 PageViewController 的数据源。

I added this to my PgeViewController class (linked to my page view controller in the storyboard, inherits both UIPageViewControllerand UIPageViewControllerDataSource):

我将此添加到我的 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
    }
}

This can then be called when each sub view appears (in this case to disable it);

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

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

I hope this helps someone out, its not as clean as I would like it but doesn't feel too hacky etc.

我希望这可以帮助某人解决问题,它不像我想要的那么干净,但不会感觉太笨拙等。

EDIT: If someone wants to translate this into Objective-C please do :)

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

回答by Austin

Edit: this answer works for page curl style only. Jessedc's answeris far better: works regardless of the style and relies on documented behavior.

编辑:此答案仅适用于页面卷曲样式。Jessedc 的答案要好得多:无论风格如何,都可以工作,并且依赖于记录的行为

UIPageViewControllerexposes its array of gesture recognizers, which you could use to disable them:

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

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

回答by jbustamante

A useful extension of UIPageViewControllerto enable and disable swipe.

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

回答by Carter Medlin

If you want your UIPageViewControllerto maintain it's ability to swipe, while allowing your content controls to use their features (Swipe to delete, etc), just turn off canCancelContentTouchesin the UIPageViewController.

如果您希望UIPageViewController保持滑动的能力,同时允许您的内容控件使用其功能(滑动删除等),只需canCancelContentTouchesUIPageViewController.

Put this in your UIPageViewController's viewDidLoadfunc. (Swift)

把它放在你UIPageViewControllerviewDidLoadfunc 中。(迅速)

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

The UIPageViewControllerhas an auto-generated subview that handles the gestures. We can prevent these subviews from cancelling content gestures.

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

From...

从...

Swipe to delete on a tableView that is inside a pageViewController

在 pageViewController 内的 tableView 上滑动以删除

回答by Darko

I solved it like this (Swift 4.1)

我是这样解决的(Swift 4.1)

if let scrollView = self.view.subviews.filter({
extension UIPageViewController {
    var isPagingEnabled: Bool {
        get {
            return scrollView?.isScrollEnabled ?? false
        }
        set {
            scrollView?.isScrollEnabled = newValue
        }
    }

    var scrollView: UIScrollView? {
        return view.subviews.first(where: { ##代码## is UIScrollView }) as? UIScrollView
    }
}
.isKind(of: UIScrollView.self)}).first as? UIScrollView { scrollView.isScrollEnabled = false }

回答by Szymon W

Swifty way for @leeanswer

@lee回答的快捷方式

##代码##