【Swift】初めて3日でもわかる値渡し🦖

#はじめに
この記事ではSwiftの基礎である**「値渡し」**を超初心者向けに解説していきます。
イメージしにくい部分は図なども使いながら説明していくので、ぜひマスターしていきましょう💪

####環境
・macOS Monterey
・Xcode version 13.1
・swift 5.5.1

#値渡しとは何か
**「値渡し」** とはある画面からある画面へ移動する（＝画面遷移）する際に、前の画面の情報を次の画面に移す作業のことを言います。

例えば、このようにある画面で文字を打ち込み、それを次のページで表したいとき。
一つ目の画面で書いた「」という文字は何のコードもなしに２つ目の画面に伝達されることはありません。
viewcontroller.swiftのようなファイル内に**「値渡し」** のコードを書いたり、storyboard上での操作をしたりすることで初めて表示できるようになるのです。

#値渡しのイメージ
<img width="500" alt="値渡しのイメージ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684427/a579fc58-d739-e2f4-2a10-8c1e6dbf4aaf.png">

1. ①の画面では②に伝える情報を準備する
2. ②の画面では①の情報を受け取る箱を準備しておく
3. 画面間の繋ぎ（＝segue）を通して②に伝える


①の画面と②の画面を繋ぐストーリーボード上の矢印（=segue）が二つのViewControllerを繋ぐ橋であるというイメージをすると分かりやすいかもしれません☺️
①と②の画面はただ画面遷移をするだけでは何の繋がりもない独立したページとなりますが、
このsegueを使って移動するときに、何かしらの処理を書くことで
①の画面の情報を②の画面へと受け渡すことができます。


#値渡しのやり方
###(例)何をしたいか
①の画面で書いた文字を②に表示させたい（＝①のTextFieldに書いた文字を②のLabelに表示させる）場合
→ ①の画面の情報を②に伝える
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684427/f3f085ac-9857-c727-1a43-4017adbc03f2.gif)



＊通常の開発の場合は、「**SNSアプリのタイムライン画面から詳細画面を表示させたい**（＝詳細表示をタイムラインの画面から詳細画面を表示させる際に、クリックした画面の固有のIDを取り出したい）」などがありそうですね💡

###どうするか
**はじめに**
①の画面　→②の画面に情報を移す準備
1.(必要があれば)ストーリーボード上で使うパーツを宣言する
2.DisplayViewControllerに移る時に呼ばれる関数を書く
3.ストーリーボード上でsegueに名前をつける

**次に**
②の画面　→①の画面の情報を受け取る準備
1.①から受け取る値の箱を作成しておく
2.受け取った後に、どうするかを書き示す

**最後に**
①の画面　→②の画面に情報を移すことを実行
3.DisplayViewControllerに移る時に呼ばれる関数の中に、①の情報を②に渡すコードを書く

###コーディング
①-1.2のコード

```Swift:ViewController
import UIKit

class ViewController: UIViewController {
    
    //①-1　(必要があれば)ストーリーボード上で使うパーツを宣言する
    @IBOutlet var textField1: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    //①-2　DisplayViewControllerに移る時に呼ばれる関数を書く
    //  DisplayViewControllerに移る時に呼ばれる場所（segueを使った画面遷移の際に呼び出される）
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     
        
    }
    
    
}   
```
①-3 のストーリーボード
![スクリーンショット 2021-12-20 1.37.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684427/60e1b4ee-aac0-01ea-3714-4283152dd9cc.png)


②-1,2のコード

```Swift:DisplayViewController
import UIKit

class DisplayViewController: UIViewController {
    
    // ②-1 ①から受け取る値の箱を作成しておく
    // ViewControllerから受け取る用の文字列の箱（→引数）
    var argString = ""
    
    @IBOutlet weak var label1: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ②-2 受け取った後に、どうするかを書き示す
        // 引数（=argString）をlabel1に表示させる（label1の文字列にargStringを代入する）
        label1.text = argString
    }
    
}
```

①-3のコード

```Swift:DisplayViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        // もし、segue(=画面間を繋ぐ矢印)のidentifierが"toDisplay"なら
        if segue.identifier == "toDisplay" {
            
            // 遷移先のViewController（=segueの行き先　=DisplayViewController）の宣言
            let nextView = segue.destination as! DisplayViewController
            
            // 「値渡し」の実行。遷移先のViewController（=DisplayViewController）のargStringにこのViewContrler上のtextField1に書かれた文字を代入
            nextView.argString = textField1.text!
        }
    }
```


###コード全体
```Swift:ViewController
import UIKit

class ViewController: UIViewController {
   
    @IBOutlet var textField1: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    // DisplayViewControllerに移る時に呼ばれる場所（segueを使った画面遷移の際に呼び出される）
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        // もし、segue(=画面間を繋ぐ矢印)のidentifierが"toDisplay"なら
        if segue.identifier == "toDisplay" {
            
            // 遷移先のViewController（=segueの行き先　=DisplayViewController）の宣言
            let nextView = segue.destination as! DisplayViewController
            
            // 「値渡し」の実行。遷移先のViewController（=DisplayViewController）のargStringにこのViewContrler上のtextField1に書かれた文字を代入
            nextView.argString = textField1.text!
        }
    }
}
```

```Swift:DisplayViewController
import UIKit

class DisplayViewController: UIViewController {
    
    // ①ViewControllerから受け取る用の文字列の箱（→引数）
    var argString = ""
    
    @IBOutlet weak var label1: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ②引数（=argString）をlabel1に表示させる（label1の文字列にargStringを代入する）
        label1.text = argString
    }
    
}
```

#まとめ
とても基礎的な知識である「値渡し」ですが、想像しにくい場面もあるかと思うので、図なども使いながら解説しました！
segueを架け橋にして画面間の情報を受け渡しているイメージをつけてもらえたら嬉しいです🌟

素敵なアプリ開発をしていきましょう💪


###参考記事
[画面遷移時の値渡しのやり方【Swift 5】](https://qiita.com/Paulownia_Friends/items/2ba93785cf926e1979b9#%E9%81%B7%E7%A7%BB%E5%85%88%E3%81%AB%E5%80%A4%E3%82%92%E6%B8%A1%E3%81%99)
[【Swift/iOS】画面遷移時の値渡し](https://capibara1969.com/1060/)