search
LoginSignup
58

More than 5 years have passed since last update.

posted at

UINavigationControllerのinteractivePopGestureRecognizerの感度を調整する

普段、左手で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が最初から頑張ればこんなことにはならなかった

上記サンプル

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
What you can do with signing up
58