LoginSignup
61
57

More than 5 years have passed since last update.

UINavigationControllerのinteractivePopGestureRecognizerの感度を調整する

Posted at

普段、左手でiPhoneを操作している人は、iOS7になってから毎日こんな経験をしているのではないでしょうか。

ひどいUXですね

これでは、本来の縦スクロール操作が慎重になってしまい、ストレスが募るばかり。。それもこれも、UINavigationControllerinteractivePopGestureRecognizer(UIScreenEdgePanGestureRecognizerクラス)の感度が高すぎるのが原因です。

そこで改善策として、UIScreenEdgePanGestureRecognizerクラスをメソッド差し替え(swizzle)して感度調整する涙ぐましい方法などがありますが、今回はそれよりももっと簡単で良い方法が見つかったので、その情報共有をします。

ヒントは、Facebookアプリでした。

interactivePopGestureRecognizer.delegateを自前で実装する(ただし、注意点あり)

標準のUINavigationControllerのジェスチャー+トランジションを使って感度調整を行っている(と思われる)アプリは、手元のインストール済みアプリの中では、Facebookだけでした。このアプリでは、

  • コンテンツのスクロール中に、interactivePopGestureRecognizerを実行しない

という上手い処理が入っているようで、似たところでは、Twitter公式アプリもそのような挙動になっていました。つまり、

// viewWillAppearあたり
self.navigationController.interactivePopGestureRecognizer.delegate = self;

...

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {

        // (1)
        if (self.tableView.dragging) return NO;

        // (2) 
        return [self.navigationController.viewControllers count] > 1;
    }
    return YES;
}

と(1)のように書くのが、よりスマートな方法と言えます。

ただし、注意点として、interactivePopGestureRecognizer.delegateを標準の_UINavigationInteractiveTransitionから勝手に奪っているので、 自己責任のもと、取り扱いにくれぐれも注意する 必要があります。(カスタムleftBarButtonItemをセット→popGestureを再度ONにした場合も同様)

One problem with this method is if you perform an edge pan on a root view it will lock up the UI

(意訳)navigationControllerのrootViewController内でinteractivePopGestureRecognizerを実行すると、UIがおかしくなるよ

この対策として、(2)も合わせて入れておくと良いでしょう。

まとめ

左利きにも優しいUIができた Appleが最初から頑張ればこんなことにはならなかった

上記サンプル

61
57
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
61
57