LoginSignup
1
3

More than 3 years have passed since last update.

[Swift]デリゲートを使用しデータをViewControllerA→B、ViewControllerB→Aに渡す

Last updated at Posted at 2020-03-24

1.はじめに

初投稿です。備忘録として書いているので、わかりにくいかもしれません。
デリゲートとプロトコルを使用して、ViewControllerB→Aに値を渡し処理するコードは以前から使っていましたが、その逆のViewControllerA→Bに渡せないかと思い試してみました。

2.試したこと

1.ViewControllerAからBにデリゲートを使用して値を送る。(PassData Forward)
2.ViewControllerBからAにデリゲートを使用して値を送る。(PassData BackWard)
詳細はコードの中にコメントを残したので番号順に追ってみてください。

3.所感

もしかしたら、使い所があるのかもしれませんが、デリゲートとプロトコルを使用してViewControllerA→Bに値を渡すのは面倒なので、シンプルにprepare(for segue)等で値を渡した方が楽に感じました。

4.コード(ViewControllerA)*動作確認済

import UIKit


//⑤(PassData Forward)プロトコルとデリゲートを使用し、ViewControllerからデータを取得し、SecondViewControllerで処理する。
protocol DataProvider: class {
    func provideData() -> String?
}

//②(PassData Forward) プロトコルDataProviderの通知先を通知先をSelfに指定。
protocol DataHandler: class {
    //prepforsegue時にproviderDelegate = selfがセットされる。
    var delegateForward: DataProvider? { get set }
}

class ViewController: UIViewController, UITextFieldDelegate {


    @IBOutlet weak var textField: UITextField!
    var name: String = ""


    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }

    @IBAction func button(_ sender: Any) {
        performSegue(withIdentifier: "goNext", sender: nil)

    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        //*ココでViewController内のプロトコルDataProviderの処理を実施すると、まだSecondViewが生成されていないため、nilとなる。
        //①(PassData Forward) よって、Delegateの通知先をプロトコルDataHandlerを通じてSecondViewControllerに伝える。
        if let destination = segue.destination as? DataHandler {
            destination.delegateForward = self
        }
        //①(PassData BackWard)Delegateの通知先をSecondViewに伝える。
        if let destination = segue.destination as? SecondViewController{
            destination.delegateBackward = self
        }
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}


//⑥(PassData Forward)
//プロトコルとデリゲートを使用し、SecondViewControllerでDelegateが呼ばれた際に以下の処理をし、SecondViewに値を渡す。
extension ViewController:  DataProvider {
    func provideData() -> String? {
        return textField.text
    }
}

//④(PassData BackWard)
//プロトコルとデリゲートを使用し、SecondViewControllerからデータを取得し、ViewControllerで処理する。
extension ViewController: provideDataBackward{
    func passData(text: String?) {
        textField.text = text
    }


}


4.コード(ViewControllerB)*動作確認済

import UIKit

protocol provideDataBackward {
    func passData(text:String?)
}



class SecondViewController: UIViewController, UITextFieldDelegate, DataHandler{

    //③(PassData Forward)プロトコルDataHandlerを通じてViewControllerで設定されたプロトコルDataProviderのDelegate通知先を記憶している。
    weak var delegateForward: DataProvider?

    //③Segue時にViewControllerで設定されたDelegateの通知先(ViewController = self)を記憶している。
    var delegateBackward:provideDataBackward?

    @IBOutlet weak var textField: UITextField!{
        didSet{
            //④(PassData Forward) ViewControllerのプロトコルDataProviderのメソッドprovideData()から値を取り出す。
            //⑦(PassData Forward) 取り出した値をテキストフィールドに表示⑦
            if let data = delegateForward?.provideData(){
                textField.text = data
            }
        }
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
        // Do any additional setup after loading the view.

    }

    @IBAction func button(_ sender: Any) {
        navigationController?.popToRootViewController(animated: true)
        // ②(PassData Backward) ViewController内でdelegateBackwardに設定された通知先(ViewController = self)にdelegateが実施されたことを伝え、データを渡す。
        delegateBackward?.passData(text: textField.text)
    }


    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }  
}

4.引用
Stack Overflow
Why passing data with delegate fails in Swift 4

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3