📌

モーダルからプッシュ遷移させる方法

2021/08/20に公開

あまりないと思いますが、モーダルからプッシュ遷移するのにとても苦戦したので備忘録。NavigationControllerについてよくわかっていなかった。
前提として、モーダルはNavigationControllerを継承したViewControllerから遷移したものです。
初学者のため、記事内容に改善点等あればご教授いただけると嬉しいです🙇‍♂️

storyboardは例えばこんな感じ。
NavigationController → FirstView → SecoundView(Model) → ThirdView(Push)

やりたいこと

  • モーダル画面からプッシュ遷移
  • モーダルにはNavigationBar(タイトルとバックボタン)を入れる(今回は簡易的にstoryboardから追加してます)
  • モーダルからプッシュ遷移した画面にもNavigationBarを入れる


結論

NavigationControllerを使用してModal遷移させ、遷移先でもNavigationControllerを使用してPush遷移させる。

FirstViewController
@IBAction func toSecondView(_ sender: Any) {
    let secondVC = self.storyboard?.instantiateViewController(identifier: "secondVC") as! SecondViewController
    let navigationController = UINavigationController(rootViewController: secondVC)
    navigationController.modalPresentationStyle = .overCurrentContext
    navigationController.setNavigationBarHidden(false, animated: true)
        
    self.navigationController?.present(navigationController, animated: true, completion: nil)
}
SecondViewController
override func viewWillAppear(_ animated: Bool) {
    navigationController?.setNavigationBarHidden(false, animated: true)
    self.navigationController!.navigationBar.isHidden = true
}
    
@IBAction func toThirdView(_ sender: Any) {
    let thirdVC = self.storyboard?.instantiateViewController(identifier: "thirdVC") as! ThirdViewController
    self.navigationController!.navigationBar.isHidden = false
    self.navigationController?.pushViewController(thirdVC, animated: true)
}
    
@IBAction func back(_ sender: Any) {
    dismiss(animated: true, completion: nil)
}
ThirdViewController
override func viewWillAppear(_ animated: Bool) {
    self.navigationController?.isNavigationBarHidden = false
}

https://youtu.be/9m7mF3fW_xk

失敗した例

普通のモーダル遷移をした後に、Segueで遷移しようとしていた。
プッシュ遷移はモーダル遷移となり、thirdViewにNavigationBarは出ない。
(今見ると仕組みわかってなくてぐちゃぐちゃ)

FirstViewController
@IBAction func toSecondView(_ sender: Any) {
    let secondVC = self.storyboard?.instantiateViewController(identifier: "secondVC") as! SecondViewController
    self.present(secondVC, animated: true, completion: nil)
}
SecondViewContoller
@IBAction func toThridView(_ sender: Any) {
    self.performSegue(withIdentifier: "toThirdView", sender: nil)
}

@IBAction func back(_ sender: Any) {
    dismiss(animated: true, completion: nil)
}
ThirdViewController
override func viewWillAppear(_ animated: Bool) {
   self.navigationController?.isNavigationBarHidden = false
}

https://youtu.be/EG4U4oPj_68

push遷移はUIViewControllerではできず、NavigationControllerを使用しないといけないらしい。
NavigationControllerにViewControllerをpushしていくことで、遷移できる。
storyboardで"show"にしたからって、push遷移するわけじゃないってことです…コードで書いた方が見やすくていいですね。
(storyboard、画面が増えるほどに重くなるので…)

【参考】
https://developer.apple.com/forums/thread/657433
https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621887-pushviewcontroller
https://developer.apple.com/documentation/uikit/uinavigationcontroller

Discussion