Как отключить жест салфетки UIPageViewController?


в моем случае родитель UIViewController содержит UIPageViewController, которая содержит UINavigationController, которая содержит UIViewController. Я хочу добавить жест салфетки к последнему контроллеру вида, но пойло обрабатывается так, как если бы они принадлежали контроллеру вида страницы. Я попытался сделать это как программно, так и через xib, но безрезультатно.

так как я понимаю, я не могу достичь своей цели, пока UIPageViewController обрабатывает его жесты. Как решить эту проблему?

13 86

13 ответов:

документированный способ предотвратить UIPageViewController от прокрутки не назначать dataSource собственность. Если вы назначите источник данных, он перейдет в режим навигации на основе жестов, который вы пытаетесь предотвратить.

без источника данных вы вручную предоставляете контроллеры вида, когда вы хотите с setViewControllers:direction:animated:completion метод и он будет перемещаться между контроллерами вида по требованию.

вышесказанное можно вывести из документация Apple UIPageViewController (обзор, второй абзац):

для поддержки навигации на основе жестов необходимо предоставить контроллеры представления с помощью объекта источника данных.

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

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

        view.scrollEnabled = NO;
    }
}

я перевожу ответ user2159978 до Свифт

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

реализация решения @lee's (@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

Edit: этот ответ работает только для стиля завиток страницы. Jessedc это гораздо лучше: работает независимо от стиля и полагается на документированное поведение.

UIPageViewController предоставляет свой массив распознавателей жестов, которые можно использовать для их отключения:

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

я боролся с этим некоторое время и думал, что должен опубликовать свое решение, следуя ответу Jessedc; удаление источника данных PageViewController.

Я добавил Это в свой класс PgeViewController (связанный с моим контроллером представления страницы в раскадровке, наследует оба UIPageViewController и 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
    }
}

это может быть вызвано при появлении каждого подвида (в этом случае, чтобы отключить его);

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

Я надеюсь, что это помогает кому-то, его нет так чисто, как хотелось бы, но не чувствовать себя слишком суховато и т. д.

EDIT: если кто-то хочет перевести это в Objective-C, пожалуйста, сделайте :)

если вы хотите UIPageViewController чтобы сохранить его способность размахивать, позволяя вашим элементам управления контентом использовать свои функции (размах для удаления и т. д.), просто выключите canCancelContentTouches на UIPageViewController.

положите это в свой UIPageViewController ' s viewDidLoad func. (Свифт)

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

The UIPageViewController имеет автоматически сгенерированный подвид, который обрабатывает жесты. Мы можем запретить этим подвидам отменять жесты содержимого.

из...

проведите по экрану, чтобы удалить tableView, который находится внутри pageViewController

полезное расширение 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
            }
        }
    }
}

похоже на @ user3568340 ответ

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

перевод ответа @user2159978 на C#:

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

благодаря ответу @user2159978.

Я делаю это немного более понятным.

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

Я решил это так (Swift 4.1)

if let scrollView = self.view.subviews.filter({.isKind(of: UIScrollView.self)}).first as? UIScrollView {
             scrollView.isScrollEnabled = false
}

(Swift 4) вы можете удалить gestureRecognizers вашего pageViewController:

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

Если вы предпочитаете в расширение:

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

и pageViewController.removeGestureRecognizers