presenting/presented VC と dismiss

モーダル遷移なら present/dismiss ・プッシュ遷移なら push/pop を使うけど、
present の関係と、 dismiss を呼んだ時の動きについてちょっとメモ

ドキュメントに書いてある通りだけど....

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621505-dismiss

presentingViewController と presentedViewController

The presenting view controller is responsible for dismissing the view controller it presented.

presenting view controller と presented view controller は紛らわしいけど、 present を使ってモーダル遷移をした時はこの関係が産まれ、プロパティにも格納される

例えば、A →(present)→ B →(present)→ C という遷移の場合は以下のような関係になる

VC presentingVC presentedVC
A nil B
B A C
C B nil

presentingViewController は自分を present した ViewController で、
presentedViewController は自分が present した ViewController になる

dismiss

この関係を把握した上でドキュメントを読むとすっきり

If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal.

ある VC で dismiss を呼んだ時は、 presentingViewController に破棄するよう依頼する
なので push 遷移してきた場合など、 presentingViewController = nil な時に dismiss してももちろん破棄されない

If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack.

複数の VC を連続して present している時に、下位の VC で dismiss すると、その presentedViewController 、さらにその presentedViewController ... と、スタックのそれより上の VC を全て破棄する

先程の例で A.dismiss すると、 B も C も dismiss される

この時、閉じるアニメーションが適用されるのは最上位の VC で、その中間の VC はアニメーションなく破棄される

まとめ

dismiss メソッドは「モーダル遷移から戻るメソッド」という理解だったけど、具体的には2つの役割があって「自身を破棄するよう依頼すること」、「自身からモーダル遷移した VC を破棄すること」をしている 👀