30
17

More than 5 years have passed since last update.

iOSアプリの「スワイプで戻る」を特定の画面でのみ無効にさせたい場合

Posted at

「スワイプで戻る」を無効にした方が良い画面

iOSアプリはデフォルトで、画面左端をスワイプする(pop gesture)ことで1つ前のViewControllerに戻ることができます。
これは便利なのですが、ドラッグジェスチャを仕込んでいるような画面、例えば「お絵描きペンツール画面」などにおいては、このジェスチャが誤発動する可能性があるため、無効にした方が良さそうです。

戻るジェスチャを無効にする方法

基本

まず、あの「スワイプで戻るジェスチャ」は、誰が管理しているのかと言うと、UINavigationControllerになります。
UINavigationControllerinteractivePopGestureRecognizer: UIGestureRecognizer?というプロパティがあります。

これを無効にすれば良いので、「戻るジェスチャを無効にしたいViewController」のviewDidAppear辺りで、以下のような実装をすればよいです。

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

これでOKといえばOKなのですが…。

各ViewControllerで各々やることの問題点

上記の実装を、「戻るジェスチャを無効化したいViewController」でそれぞれ行うのは、あまり良くないです。

  • 有効に戻し忘れてはいけない
  • 無効な画面が2つ以上連続する場合とか、「falseにする」「trueにする」タイミングを慎重に検討しないといけない

これらがあるので、出来れば個々に実装するのはやめて、ズバッと一気に対応したい。

UINavigationControllerDelegate で対応すれば良い

以下の方法で実装することをおすすめします。

  • UINavigationControllerDelegatenavigationController(_:didShow:animated:)のタイミングで処理
  • 「表示された子ViewController」が「戻るジェスチャを無視するべき」なのか否かをチェックし、その結果を反映

予め「戻るジェスチャを無視するべき」を意味するプロトコルを定義しておきます。

protocol NonSwipeable {}

戻るジェスチャを無視したいViewControllerは、このプロトコルに準拠させます。

あとは、UINavigationControllerDelegateで以下の処理を行えばOK。

func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
    navigationController.interactivePopGestureRecognizer?.isEnabled = !(viewController is NonSwipeable)
}

こうしておけば、普通の画面(戻るジェスチャは有効であるべき)に遷移した際に、ちゃんとジェスチャを有効に戻してくれます。

30
17
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
30
17