「スワイプで戻る」を無効にした方が良い画面
iOSアプリはデフォルトで、画面左端をスワイプする(pop gesture)ことで1つ前のViewControllerに戻ることができます。
これは便利なのですが、ドラッグジェスチャを仕込んでいるような画面、例えば「お絵描きペンツール画面」などにおいては、このジェスチャが誤発動する可能性があるため、無効にした方が良さそうです。
戻るジェスチャを無効にする方法
基本
まず、あの「スワイプで戻るジェスチャ」は、誰が管理しているのかと言うと、UINavigationController
になります。
UINavigationController
にinteractivePopGestureRecognizer: UIGestureRecognizer?
というプロパティがあります。
これを無効にすれば良いので、「戻るジェスチャを無効にしたいViewController」のviewDidAppear
辺りで、以下のような実装をすればよいです。
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
これでOKといえばOKなのですが…。
各ViewControllerで各々やることの問題点
上記の実装を、「戻るジェスチャを無効化したいViewController」でそれぞれ行うのは、あまり良くないです。
- 有効に戻し忘れてはいけない
- 無効な画面が2つ以上連続する場合とか、「falseにする」「trueにする」タイミングを慎重に検討しないといけない
これらがあるので、出来れば個々に実装するのはやめて、ズバッと一気に対応したい。
UINavigationControllerDelegate
で対応すれば良い
以下の方法で実装することをおすすめします。
-
UINavigationControllerDelegate
のnavigationController(_:didShow:animated:)
のタイミングで処理 - 「表示された子ViewController」が「戻るジェスチャを無視するべき」なのか否かをチェックし、その結果を反映
予め「戻るジェスチャを無視するべき」を意味するプロトコルを定義しておきます。
protocol NonSwipeable {}
戻るジェスチャを無視したいViewControllerは、このプロトコルに準拠させます。
あとは、UINavigationControllerDelegate
で以下の処理を行えばOK。
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
navigationController.interactivePopGestureRecognizer?.isEnabled = !(viewController is NonSwipeable)
}
こうしておけば、普通の画面(戻るジェスチャは有効であるべき)に遷移した際に、ちゃんとジェスチャを有効に戻してくれます。