【Swift】画面遷移の方法（俯瞰用）

値の受け渡しや求めるUIに合わせた記述の仕方など、単純に見えてバリエーションの多い画面遷移についてまとめます。
performSegueやら、popViewControllerやら、dismissやら、InterfaceBuilderやら、コーディングやら地味にバリエーションが多くてめんどくさくないですか？
今まで経験則でなんとなく使ってきましたが、詰まってはググってを繰り返していたので一度使い方をまとめたいと思います。
備忘録的な記事になりますが、ご容赦願います。

# 画面遷移で混乱すること
 - コーディングとかInterfaceBuilderとか実装方法がいくつかあって忘れる
 - 遷移の種類がいくつかあって混乱する（showとかmodalとか）
 - 画面間の値の受け渡しでコケる
 - 画面から戻るときにコケる
 - 上記の組み合わせで実装方法が違って泣く

僕は上記のようなことでよく詰まります。
ですので、以下ではこの辺をなんとなく整理できたらなと思います。

# 画面遷移の実装方法

画面遷移の実装方法は主に以下の三つ。
**A. InterfaceBuilder（ボタンと画面をSegueで接続）**
**B. InterfaceBuilder（Segue Identifier） + コーディング**
**C. InterfaceBuilder（Storyboard ID） + コーディング**

ボタンを押したら遷移するだけなどの簡単な処理はAパターンで良いとして、
多くの場合はボタン押下時になんらかの処理を実行するケースが多いと思います。
それに伴いBパターン、Cパターンもしっかり使えるようになっておく必要があります。

### B. InterfaceBuilder（Segue Identifier） + コーディング
遷移元・先のViewControllerをSegueで繋げた後に、SegueのIdentifierを設定。
その際に画面遷移の種類（Show,Present Modalyなど）を指定することができます。
これにより遷移したいタイミングで

```Swift
performSegue(withIdentifier : "toNextViewController", sender: nil)
```

などとすることで遷移を実行できます。
ちなみにsenderによってボタンからの遷移実行なのかtapGestureRecognizerなのか、segueの出し元の判定ができます。

### C. InterfaceBuilder（Storyboard ID） + コーディング
遷移先のStoryboardにIDを振り、コードでそのViewControllerを呼び出します。
実際のコード例は以下。

```Swift
// Storyboard、ViewControllerを指定
// 同じStoryboard上であればselfを用いて指定
let storyboard: UIStoryboard = self.storyboard!
let next: UIViewController = storyboard.instantiateViewController(withIdentifier:"nextViewController") as! UIViewController
// 遷移処理
navigationViewController.pushViewController(next, animated: true, completion: nil)
```

Storyboard IDを利用して遷移先のViewControllerのインスタンスを取得した後に、遷移先の処理を実行します。

# 画面遷移の種類
画面遷移のバリエーションは5つ？くらいあるけど、実際よく使うのは、
**Show** と **Present Modaly**　の二つと思われます。
一旦それ以外の遷移の種類は忘れることとして、それぞれについてまとめます。

## Show

遷移元の画面から横にズイっと新しい画面が現れる遷移。
NavigationControllerの管理下で使うことが多いです。
rootViewControllerに対して次々にShowで画面を繋げた場合、
Showで繋げたviewcontrollerはrootViewControllerの子となります。

NavigationController管理下における、
A_ViewController　->　B_ViewControllerへの遷移では、
pushViewControllerメソッドを用いて、showの遷移が可能です。
（先ほどCパターンの実装例であげた実装例）

```Swift:AViewContoller.swift
let next: UIViewController = storyboard.instantiateViewController(withIdentifier:"nextViewController") as! B_ViewController
navigationViewController.pushViewController(next, animated: true, completion: nil)
```
また、遷移先のB_ViewControllerから遷移元に戻るときは、popViewControllerメソッドを使うことで遷移元に戻ることができます。

```Swift:BViewContoller.swift

navigationViewController.popViewController(animated: true)
```

## Present Modaly

Viewの上に覆いかぶさるような形で下から新たなViewが現れる遷移。
一時的なユーザーの操作受付やオンボーディングからアプリの本機能への遷移時など、つながりをあえて切りたいときによく使われます。
iOS13以降ではデフォルトの遷移がフルスクリーンではなく、Safariのタブのような重なり方となっており、必要に応じてフルスクリーンの設定が必要になります。

このパターンでも同様に、
A_ViewController　->　B_ViewControllerへの遷移を考えたとき、
遷移元からは

```Swift:A_ViewContoller.swift
let next: UIViewController = storyboard.instantiateViewController(withIdentifier:"nextViewController") as! B_ViewController
self.present(next,animated: true, completion: nil)
```
にて遷移ができ、遷移先からは


```Swift:B_ViewContoller.swift
self.dismiss(animated: true, completion: nil)
```

dismissメソッドにて遷移元に戻ることが可能です。

# まとめ

今回画面遷移の方法について、実装方法・代表的な遷移の種類・各メソッドの位置付けをまとめました。
今回書ききれなかった画面間の値渡しや、画面遷移時の処理など、時間のあるときに書きたいと思います。
見ていただいた方、ありがとうございました。

# 参考
[【iOS】画面遷移方法まとめ](https://qiita.com/eg_19_/items/54baed2ac374ac969100 "Qiita")
[【Swift/iOS】遷移元画面への戻り方](https://ja.stackoverflow.com/questions/55739/label-text%E3%82%92%E9%81%95%E3%81%86%E7%94%BB%E9%9D%A2%E3%81%8B%E3%82%89%E6%93%8D%E4%BD%9C%E3%81%97%E3%81%9F%E3%81%84%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8C%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AB%E3%81%AA%E3%82%8B)
[【Swift/iOS】Segueを使わない画面遷移](https://capibara1969.com/684/)