検証環境:
Xcode 11.1
Swift 5.1
例えば Universal Links などの機能を使ってディープリンクで深い階層に一気に遷移させたい場合などに使える。
UINavigationController の setViewControllers(_:animated:)
というメソッドがあるので、この引数に複数の ViewController を渡せばよい。
以下実装例。
まず、RootViewController には ViewControllerA
クラスが設定されている。
ここに ViewControllerB、ViewControllerC、ViewControllerD の順に push したのと同じ状態を setViewControllers を使って作る。
pop で最終的に ViewControllerA にまで戻りたいのであれば、表示中の ViewControllerA についても配列の最初に追加する必要がある。
// ViewControllerA @IBAction func handleButton(_ sender: UIButton) { let sb = UIStoryboard(name: "Main", bundle: nil) let vcB = sb.instantiateViewController(identifier: "ViewControllerB") let vcC = sb.instantiateViewController(identifier: "ViewControllerC") let vcD = sb.instantiateViewController(identifier: "ViewControllerD") navigationController?.setViewControllers([self, vcB, vcC, vcD], animated: true) }
用意した遷移ボタン押下すると上記 handleButton
メソッドが呼ばれる。
挙動としては ViewControllerB
、ViewControllerC
はスキップし、ViewControllerD
が表示される。
この時の ViewController のライフサイクルは、遷移元のViewControllerA
とViewControllerD
のみ呼ばれる。
ViewControllerD:viewDidLoad() ViewControllerA:viewWillDisappear(_:) ViewControllerD:viewWillAppear(_:) ViewControllerA:viewDidDisappear(_:) ViewControllerD:viewDidAppear(_:)
この状態から戻るボタンで pop させるとViewControllerC
の読み込みが開始される。
ViewControllerC:viewDidLoad() ViewControllerD:viewWillDisappear(_:) ViewControllerC:viewWillAppear(_:) ViewControllerD:viewDidDisappear(_:) ViewControllerC:viewDidAppear(_:)
さらに戻るとViewControllerB
が読み込まれる。
ViewControllerB:viewDidLoad() ViewControllerC:viewWillDisappear(_:) ViewControllerB:viewWillAppear(_:) ViewControllerC:viewDidDisappear(_:) ViewControllerB:viewDidAppear(_:)
さらに戻ると最初のViewControllerA
が表示される。
ViewControllerB:viewWillDisappear(_:) ViewControllerA:viewWillAppear(_:) ViewControllerB:viewDidDisappear(_:) ViewControllerA:viewDidAppear(_:)