[Swift] 値を別の画面に渡す方法

以下の2つのViewController(FirstVC、SecondVC)があるとして、互いのプロパティに値を受け渡す方法を紹介します。


FirstVC -> SecondVCに遷移する時に値を渡す方法。

import UIKit
class FirstVC: UIViewController {
   var num1: Int?
   override func viewDidLoad() {
       super.viewDidLoad()
   }
   @IBAction func goSecondVC(_ sender: Any) {
       let secondVC = storyboard?.instantiateViewController(withIdentifier: "SecondVC") as? SecondVC
       if let secondVC = secondVC {
           secondVC.num2 = 2 //値を受け渡す
           present(secondVC, animated: true, completion: nil)
       }
   }
   
}

storyboardからSecondVCクラスを取得して、値の受け渡しと画面遷移を行なっています。

storyboardで以下の設定をしないとSecondVCが取得できないので注意してください。

これで値が受け渡されます。


SecondVC -> FirstVCに遷移する時に値を渡す方法。

Second -> FirstVCに遷移する方法が、

present(firstVC, animated: true, completion: nil)

で遷移するなら、FirstVC -> SecondVCのときと同じやり方で出来ますが、

それだと画面遷移する度にFirstVCやSecondVCが作られてメモリを圧迫してしまいます。なので、SecondVC -> FirstVCに遷移する時はSecondVCを破棄することで遷移した方がいいでしょう。

dismiss(animated: true, completion: nil)

↑これを使ってです。


そして、問題はまだあります。

FirstVC -> SecondVCに値を受け渡すのに、storyboardからSecondVCクラスを取得しましたが、

これは新たにSecondVCクラスを生成しているので、遷移前のFirstVCとは別のインスタンスになります。

なので、SecondVCでFirstVCクラスを生成して値を受け渡し、dismissで破棄してFirstVCに戻っても、戻った先のFirstVCには値が受け渡されていません。別のインスタンスに値を受け渡した訳です。

ならば、FirstVCにプロパティでSecondVCを保持させて、画面が戻ってきた時はviewWillAppearとかでsecondVCから値を取得すれば良いではないかと思いました。以下がそのコードです。

import UIKit

class FirstVC: UIViewController {
   var num1: Int?
   var secondVC: SecondVC?

   override func viewDidLoad() {
       super.viewDidLoad()
       secondVC = storyboard?.instantiateViewController(withIdentifier: "SecondVC") as? SecondVC
   }
   
   override func viewWillAppear(_ animated: Bool) {
       if secondVC?.backFlag == true {
           secondVC?.backFlag = false
           num1 = secondVC?.num1
       }
       
   }

   @IBAction func goSecondVC(_ sender: Any) {
       if let secondVC = secondVC {
           secondVC.num2 = 2 //値を受け渡す
           present(secondVC, animated: true, completion: nil)
       }
   }
   
}
import UIKit

class SecondVC: UIViewController {
   var num2: Int?
   var num1: Int? //FirstVCに受け渡したい値
   var backFlag: Bool = false

   override func viewDidLoad() {
       super.viewDidLoad()
   }
   @IBAction func closeButton(_ sender: Any) {
       num1 = 1
       backFlag = true
       dismiss(animated: true, completion: nil)
   }
}

この方法で、SecondVC -> FirstVCへの値の受け渡しは成功しました。

SecondVCのインスタンスは残ったままですが、増え続けることはないのでこれで良しとしましょう。


別の受け渡し方法でクロージャを使ったものもありますが、後日書きます。





この記事が気に入ったらサポートをしてみませんか?