web-dev-qa-db-ja.com

悪いプログラミングの結果:dismissViewControllerとpopViewController

説明されているように、dismissViewControllerAnimated:completion:popViewControllerAnimated:の違いを理解しています Stack Overflowで そしてここで:

-dismissViewControllerAnimated:completion:メソッドは、メソッド-presentViewController:animated:completion:によって提示されたUIViewControllerを閉じるために使用されます。

UINavigationControllerの-popViewControllerAnimated:メソッドは、UINavigationControllerの-pushViewController:animatedメソッドで示されるコントローラーをポップするために使用されます。

最近、アプリで間違いを見つけました。[self dismissViewControllerAnimated:completion:]を使用して、ナビゲーション埋め込みアプリでプッシュで表示されたVCを却下しました。必要なときにフライドポテトを揚げました。ピザを食べました。すべてが正常に機能し、VCが期待どおりに割り当て解除されたため、間違いを見つけられませんでした。

私の質問:これら2つの方法を混ぜ合わせた結果はどうなりますか?

18

-presentViewController:animated:completion:-pushViewController:animated:は異なる意味です。前者は「自分を置き換えるためにこの他のViewControllerを提示する」と言っています。後者は、「制御しているリストの一部として、この他のViewControllerを自分の中に表示する」と言っています。

つまり、移行後に誰がディスプレイを担当すると見なされるかということです。前者の場合、ナビゲーションコントローラーは制御を放棄します。後者では、それは制御を保持します。

前者の機能はUIViewControllerによって提供されます。後者はUINavigationControllerに固有です。

2つのアクションはまったく異なるため、反対のアクションは別々です。ナビゲーションコントローラーはdismissViewController:...をキャッチし、名前付きコントローラーがどのように提示されたかを確認し、スーパークラスまたはpop...に分岐しますが、設計と保守の観点からは、タスクの混同は魅力的ではありません。

ナビゲーションコントローラーは、あるものを別のものにマップすることを約束しておらず、渡したコントローラーが以前に提示されていない場合、UIViewControllerは特定の動作を約束しないので、あなたの文字通りの答えだと思います問題は、これら2つのことを混ぜ合わせた結果は未定義の動作です。

17
Tommy

私がこれを最もよく説明できるかどうかはわかりませんが、試してみましょう。

私は現在タブベースのアプリに取り組んでおり、各タブには独自のナビゲーションコントローラーがあります。サイド機能については、モーダルビューに分岐するnavbarブランチにbarbuttonitemがあります(場合によっては、特定の機能のパスのバックスタックを制御するための新しいナビゲーションコントローラーへのモーダルです。

モーダルとして別のナビゲーションコントローラーから起動するナビゲーションコントローラーのルートビューでdismissViewControllerを呼び出します。 (それが理にかなっていることを願っています。)

多分これはより良いです:

提示されたビューコントローラーは、提示されたビューコントローラーを閉じる責任があります。提示されたビューコントローラー自体でこのメソッドを呼び出すと、メッセージが提示されたビューコントローラーに自動的に転送されます。

複数のView Controllerを連続して提示し、提示されたView Controllerのスタックを構築する場合、スタックの下位にあるView Controllerでこのメソッドを呼び出すと、その直接の子ViewControllerとすべてが閉じられます。スタック上のその子の上のビューコントローラ。これが発生すると、最上位のビューのみがアニメーション化されて閉じられます。中間のビューコントローラはスタックから削除されるだけです。最上位のビューは、モーダル遷移スタイルを使用して閉じられます。これは、スタックの下位にある他のView Controllerで使用されているスタイルとは異なる場合があります。

ナビゲーションベースのViewControllerをプッシュし、必要に応じてpopViewControllerを使用します。ナビゲーションから分岐するものをモーダルに導入し、その場合は必要に応じてdismissViewControllerを使用します。

1
William Riley