web-dev-qa-db-ja.com

UIPageViewControllerのスワイプジェスチャーを無効にするにはどうすればよいですか?

私の場合、親UIViewControllerにはUIPageViewControllerが含まれていますUINavigationControllerにはUIViewControllerが含まれています。最後のView Controllerにスワイプジェスチャーを追加する必要がありますが、スワイプはPage View Controllerに属しているかのように処理されます。プログラムとxibの両方でこれを実行しようとしましたが、結果はありませんでした。

ですから、UIPageViewControllerがジェスチャーを処理するまで、目標を達成できません。この問題を解決するには?

110
user2159978

UIPageViewControllerがスクロールしないようにする文書化された方法は、dataSourceプロパティを割り当てないことです。データソースを割り当てると、「ジェスチャベース」ナビゲーションモードに移行します。これは、防止しようとしているものです。

データソースがない場合、setViewControllers:direction:animated:completionメソッドを使用する場合は手動でView Controllerを提供し、必要に応じてView Controller間を移動します。

上記は IPageViewControllerのAppleのドキュメント (概要、2番目の段落)から推測できます。

ジェスチャーベースのナビゲーションをサポートするには、データソースオブジェクトを使用してView Controllerを提供する必要があります。

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

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

        view.scrollEnabled = NO;
    }
}
79
user2159978

ser2159978の答えをSwiftに変換します

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

@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
24
LinusGeffarth

Edit:この回答はページカールスタイルにのみ有効です。 Jessedcの答え ははるかに優れています。スタイルに関係なく動作し、文書化された動作に依存します

UIPageViewControllerは、ジェスチャー認識機能の配列を公開します。これを使用して、それらを無効にすることができます。

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

私はしばらくの間これと戦ってきましたが、Jessedcの答えに続いて、自分の解決策を投稿すべきだと考えました。 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)
}

これが誰かの助けになることを願っています。それは私が望むほどきれいではありませんが、あまりにもハック感は感じません。

編集:誰かがこれをObjective-Cに翻訳したい場合は、してください:)

8
Jamie Robinson

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

UIPageViewControllerのスワイプ機能を維持しながら、コンテンツコントロールで機能の使用(スワイプによる削除など)を許可する場合は、canCancelContentTouchesUIPageViewControllerをオフにします。

これをUIPageViewControllerviewDidLoad funcに入れます。 (迅速)

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

UIPageViewControllerには、ジェスチャを処理する自動生成されたサブビューがあります。これらのサブビューがコンテンツジェスチャをキャンセルしないようにすることができます。

から...

pageViewController内にあるtableViewでスワイプして削除

5
Carter Medlin

このように解決しました(Swift 4.1)

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

@ user3568340 answerに似ています

スイフト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
        }
    }
1

@ user2159978の回答に感謝します。

わかりやすくします。

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

@ lee answerの迅速な方法

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
    }
}
0
Szymon W

(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
Miguel

次のように宣言します。

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

次に、次のように使用します。

scrollView?.isScrollEnabled = true //false

@ user2159978の応答をC#に翻訳する:

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