LoginSignup
1
1

UINavigationViewControllerの戻る(pop)をisMovingFromParentで判定するのは危険

Last updated at Posted at 2022-10-17

ナビゲーションを使っている場合に「戻るボタン」で戻ったことを判定するのにviewWillDisappear内でisMovingFromParent == trueを使う方法がググると結構出てきます。
※Qiita内だと https://qiita.com/yimajo/items/d9409d83fecf9875061d とか。

が、うまく動作しないパターンをいくつか見つけたので記録しておきます。

検証用Xcodeプロジェクト

検証用に作ったXcodeプロジェクト: https://github.com/pomu0325/isMovingFromParent

image.png

  • NavigationControllerに以下のViewControllerを埋め込む
    • ViewController(背景黒いやつ)
      • PushボタンでViewController2を表示
    • ViewController2(背景白いやつ)
      • animated: trueのボタンでsetViewControllers([viewController], animated: true)する
      • animated: falseのボタンでsetViewControllers([viewController], animated: false)する
      • viewWillDisappear内でprint("isMovingFromParent: \(isMovingFromParent)")して状態を調べる

正しく判定できないケース

以下の操作や処理をすると、viewWillDisappearisMovingFromParentでは戻ったかどうかが正しく判定できません。

スワイプで戻ろうとして途中でやめたとき

最近のiOSだと画面左端からのスワイプでナビゲーションの「戻る」ができますが、途中で指を離したり戻したりすると「やっぱやめた」ができます。

swipeback.gif

が、スワイプを始めたタイミングでviewWillDisappearが呼ばれ、このタイミングでもisMovingFromParenttrueになっているので「やっぱやめた」場合に「戻る」判定を早まってしまいます。

https://qiita.com/yimajo/items/d9409d83fecf9875061d#comment-a08822f1e2081fe33bb0 のコメントでも言及されていました

animated: falsesetViewControllersした時

直接ビューのスタックを書き換えたい時に使えるsetViewControllersをした際に「戻る」操作はしていないので除外したいことがありisMovingFromParentで判定をしていました。

意外にもanimatedの指定次第でisMovingFromParentが変わってしまいます。

  • animated: trueの場合: isMovingFromParent == falseになる
  • animated: falseの場合: isMovingFromParent == trueになる

ので、誤判定されてしまいます。

1
1
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
1
1