[Swift]アプリに画面遷移を追加する方法

この記事は前回の[[Swift]カウントアップアプリを作ってSwiftを触ってみよう](https://qiita.com/appgrape/private/ead85f5267d4d7894084)の続きです。

#アプリの完成形はこちら
<img src= "https://camo.qiitausercontent.com/bc62f68ea37382fbda82196e22077d59a5746394/68747470733a2f2f757365722d696d616765732e67697468756275736572636f6e74656e742e636f6d2f33353639343934362f38393439333232392d61613731653238302d643765652d313165612d383464612d3662306137313035386665632e676966" width="300">


#ソースコードはこちらから
https://github.com/techiro/CountUpAppForBeginners/tree/v1

---

#画面遷移で抑えておきたいポイント
- 画面遷移先のViewController
- ViewControllerとプログラムコードとの繋がり
- Segueという概念

---

#画面遷移先のViewController
画面遷移するために新しいViewControllerを追加
ボタンなどを追加したLibraryから`ViewController`を選択してドラッグ&ドロップ

<img width="1680" alt="スクリーンショット_2020-08-05_11_20_23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/8a05bf48-21f5-e55c-fd63-98299c2e9965.png">

<img width="1414" alt="スクリーンショット_2020_08_07_23_41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/0a40d9ec-b07b-eb88-93ad-6e24fe7d3e95.png">

画面にViewControllerが追加されたらOK

---

#ViewControllerとプログラムコードとの繋がり

1．画面から新しいViewControllerを選択

<img width="208" alt="スクリーンショット 2020-08-08 0.20.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/3729c899-c3ba-3a16-c3ac-a83515d31ef5.png">

2．Identity inspectorを選択

**新しく追加したViewControllerのCustom Classが空になっている**
<img width="1417" alt="スクリーンショット_2020_08_07_23_41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/ade20cec-2935-6811-3ddf-c3e549416367.png">

このままだと画面遷移を行えないので、新しいClassを定義しなければならない。

##新しいClassを定義
画面左下の＋ボタンをクリック→NewFileをクリック
<img width="340" alt="スクリーンショット 2020-08-08 0.00.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/2028791e-7559-d0f4-94d7-f9862ac6d739.png">

`Cocoa Touch Class`→`Next`

<img width="1680" alt="スクリーンショット 2020-08-08 0.03.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/89cefcec-2575-ebeb-5713-28f435b9e80a.png">

###Class名`NextViewController`に変更

<img width="729" alt="スクリーンショット 2020-08-08 0.04.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/41ab9864-8751-c800-bb4c-f4e5ede30bf0.png">

###Subclass of: UIViewControllerに変更
この項目はClassがどんな用途で使われるかを設定でき、初期段階で必要なプログラムをXcodeが書いてくれます。
<img width="729" alt="スクリーンショット 2020-08-08 0.06.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/cc859693-87ca-12f1-048c-58b932d310d1.png">
例えばここで`UITableViewController`を選ぶとテーブルを使うためのコードを自動で入力してくれます。

###入力を終えたら`Next`
最後にファイルの保存場所を聞いてきます。
そのまま`Create`を押してください


<img width="828" alt="スクリーンショット_2020_08_08_0_17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/d2abfd2f-e8f1-7de7-3181-93608a7fba3a.png">

---

##新しいViewControllerに新しいClassを紐づける

StoryBoardに戻って追加したViewControllerを選択
<img width="208" alt="スクリーンショット 2020-08-08 0.20.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/d11563df-dfa4-ed10-ebd2-2d7ff03f353b.png">

<img width="825" alt="スクリーンショット_2020-08-08_0_26_57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/71a08087-ff7e-59e1-bcb3-414788c7b0df.png">

これで新しいViewControllerに新しいClassを紐づけることができました！

---

##Segueという概念
Segueとは、storyboard上で画面遷移を表す部品です。
Segueは、**画面遷移の方法**と、**どう画面遷移させるか**を決めることができます。

###詳しく説明しているサイトを紹介
- [【Swift/iOS】Segueを使った画面遷移](https://capibara1969.com/229/)
- [【Swift】画面遷移の方法まとめ](https://qiita.com/misakiagata/items/b7f6c2f6c9f988ec38c7)

ボタンに対してSegueを作成することもできます。
例えば、「設定ボタンをタップしたら設定画面に遷移する。」を実現したい場合はノンコーディングで画面遷移を行うことができます。

今回使用する方法はViewControllerからSegueを作成してコーディングを行って画面遷移を実装します。

---

##Segueを作成
ViewControllerを選択→`⌃(control)` + `ドラッグ&ドロップ`

Manual Segueは`Present Modally`を選択
![2020_08_08_00_35.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/1e955d52-486f-f91d-8c5d-f564e992558b.gif)

ViewControllerと新しいViewControllerがつながっていればOK
マークが違っていても画面遷移の見え方が変わるだけで、問題ないです。
<img width="203" alt="スクリーンショット_2020_08_08_0_50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/b078208f-f140-3515-48ff-36855402fec6.png">

---

##Segueに名前をつける
Segueを選択→`Attribute inspector`→`Identifire`
→任意の名前をつける(今回は`next`)
<img width="1116" alt="スクリーンショット_2020-08-08_0_54_04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/3ad33244-b831-6e47-3f72-f410c1304bf6.png">

##SegueのPresentationをFullScreenに変更(任意)
変更すると、画面全体にViewが表示されます。
<img width="431" alt="スクリーンショット_2020-08-09_14_35_04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/d255e9a2-d867-3d92-c63d-6f4c99147046.png">

---

##遷移先のViewControllerに戻るボタンを設置
`NextViewController`に戻るボタンを新しく設置します.

`Main.storyboard`→`+ボタン`→`Button`を選択して`NextViewController`ドラッグ&ドロップ

それが完了したら、ボタンを選択してTitleをわかりやすい文字に変更してください。
<img width="860" alt="スクリーンショット_2020_08_08_1_14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/8db2f857-ed14-5b79-bd33-251f28814611.png">

##ボタンを`NextViewController`クラスと紐づける

- `三マーク`をクリック→Assistantエディタを起動
**StoryBoardとコードを一緒にみることができる**
<img width="692" alt="Xcode_InterfaceBuilderKit_DocumentGearMenu.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/c241d881-e905-1e4a-d9e6-a643e01c4737.png">

- 戻るボタンをクリック→ `⌃control` +`ドラッグ&ドロップ` 

`NextViewController`クラスにボタンを紐づける

###紐付けポイント
- Connection→Actionになっているか確認
<img width="733" alt="スクリーンショット_2020_08_08_14_04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/f0405ef2-fda2-4bf7-5617-81124a879227.png">

###下準備は終了。画面遷移のコードを書いていく

---

#画面遷移するためのコード
画面遷移をさせるためのコードはこれだけ

```swift
performSegue(withIdentifier: "next", sender: nil)
```

これを画面遷移させたい場所に書くだけで画面遷移します。

---

##試しにやってみる

前回の記事[[初心者向け]カウントアップアプリを作ってSwiftを触ってみよう](https://qiita.com/appgrape/private/ead85f5267d4d7894084)で`countUpButton`を作成したので、
`count`が2になったら画面遷移するようにコードを書いていきます。



```swift:ViewController.swift内
    @IBAction func countUpButton(_ sender: Any) {
        //+ボタンを押すとラベルの文字をカウントアップ
        count = count + 1
        
        //画面遷移
        if count == 2 {
            performSegue(withIdentifier: "next", sender: nil)
            count = 0
        }
        
        countLabel.text = String(count)
        
        //カウントにあわせて文字の色を変更
        changeColor()

    }
```

## ⌘ + Rで実行

画面遷移できました🥳

---

#画面遷移から戻る方法
これもたった1行で完了します。

```swift
dismiss(animated: true, completion: nil)
```
これを画面遷移させたい場所に書くだけで画面遷移します。

---

##試しにやってみる


```swift:NextViewController.swift内
    @IBAction func backButton(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }
```

## ⌘ + Rで実行

###画面遷移から戻ることができました🥳

---

#画面遷移を行いながら値を渡す方法
画面遷移が無事終わったら、画面遷移を行う際に値も一緒に渡してみましょう！
今回は一般的に使われている方法を紹介します。

##NextViewController.swiftに値を渡すための準備
- 画面に値を表示するためのLabelを設置(＋ボタンからUIパーツLabelを選択→`NextViewController.swift`と紐づける。)
- ViewControllerから値をもらうための変数`passdata`を定義
- label.text = String(passdata)でLabelに値を反映

<img width="720" alt="スクリーンショット 2020-08-09 14.21.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240708/774ea764-5706-6bd1-782f-c98320403fd1.png">


```swift:NextViewController.swift
@IBOutlet weak var label: UILabel!
var passdata = 0
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        label.text = String(passdata)
    }
```

---

##値を渡すためのメソッドを定義
`prepare(for segue: UIStoryboardSegue, sender: Any?) `メソッドを定義

```swift:ViewController.swift
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     //引数segueの中に画面遷移に関する情報が含まれている。
        if segue.identifier == "next" {
           //NextViewControllerに値を渡す処理を書く。
        }
    }
```

`performSegue(withIdentifier: "ID", sender: nil)`で画面遷移を行うと自動的に、
`prepare(for segue: UIStoryboardSegue, sender: Any?) `メソッドが呼ばれます。

これはSegueが実行されようとしていることをView Controllerに通知するメソッドです。

###このメソッドを使用して、新しいViewControllerに値を渡すことができます。 



##注意点
このメソッドはSegueが実行されようとしていることを通知するので、複数のSegueから呼び出されます。
したがって、`if segue.identifier == "next"{・・・}`のように`next`のSegueからの情報かどうかを判定してから値を渡す処理を書く必要があります.

---

##メソッド内に処理を書く
```swift:ViewController.swift

    @IBAction func countUpButton(_ sender: Any) {
            //中略
            //画面遷移
            performSegue(withIdentifier: "next", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "next" {
            let nextVC = segue.destination as! NextViewController
            nextVC.passdata = count
            
        }

```

##⌘ + R　で実行

`performSegue(withIdentifier: "next", sender: nil)`を実行した時の`count`の値を渡すことができました!

---

##今回やったこと
- 新しいViewControllerを作成して画面遷移を実装
- ViewControllerとプログラムコードとの繋がり
- Segueという概念の理解

---


以上でカウントアップアプリのチュートリアルは終わりです。
お疲れ様でした！

#もっと深掘りしたい方

この続きとして、
[カウントアップアプリを改造して,通知をn秒後に通知を出してみる (n>0)](https://qiita.com/tessy0901/items/c261359880f1bc2d80b5)
の記事も参考にしてみてください！


##最後に
最後までご覧いただきありがとうございます。
[Twitter](https://twitter.com/appgrape)で主にSwiftについてのツイートをしているのでのぞいてみてください！

今回はSwiftの言語についてあまり詳しく説明しませんでしたが、
[ここ](https://kacchanblog.com/category/programming/swift)でもっと詳しい記事を書いているのでSwiftに興味が湧いた方は参考にしてみてください！