【2024年4月】弊社では、基本リモートワークで一緒に成長してくださるメンバーを広く募集させていただいております。 詳細はこちら

【Swift】画面間のデータ受け渡しをデリゲート(Delegate)やクロージャー(Closure)を使って実装する方法をサンプルコードを示しながら徹底解説!

【Swift】画面間のデータ受け渡しをデリゲート(Delegate)やクロージャー(Closure)を使って実装する方法をサンプルコードを示しながら徹底解説!
ふくしま

こんにちは!株式会社メモリアインクのふくしまです!

この記事では、Swiftにおける画面間のデータの受け渡しをデリゲートやクロージャーを利用して実装する方法をサンプルコードを示しながら解説していきます。

この記事を読んで分かること…
・デリゲート(delegate)を使った画面間のデータ受け渡し方法
・クロージャーを使った画面間のデータ受け渡し方法

デリゲートやクロージャーについて知らないよって方は、以下の記事で詳しく解説していますので、併せてご確認ください!

目次

デリゲートを使ったデータ受け渡しの実装方法

概要

遷移先の画面のテキストフィールドに入力した文字を、遷移元の画面に表示する実装を例に解説します。
実際の開発では例えば以下のような場面で利用されます。

  • ユーザーがアイテムを選択した際に、そのアイテムの詳細情報を表示する画面にデータを渡す。
  • フォーム画面から、ユーザーが入力した情報を確認画面や結果表示画面に渡す。

UI設計

遷移先の画面(SecondViewController)

・遷移元の画面に受け渡すデータ入力のためのUITextField
・遷移元へデータを受け渡すためのボタンUIButton

【Swift】画面間のデータ受け渡しをデリゲート(Delegate)やクロージャー(Closure)を使って実装する方法をサンプルコードを示しながら徹底解説!

遷移元の画面(ViewController)

・遷移先で入力した文字を表示するためのテキストUILabel
・次画面へ遷移するためのボタンUIButton

【Swift】画面間のデータ受け渡しをデリゲート(Delegate)やクロージャー(Closure)を使って実装する方法をサンプルコードを示しながら徹底解説!

画面遷移については以下の記事で解説していますので、併せてご覧ください!

SecondViewControllerの実装

サンプルコード

import UIKit
protocol SecondViewControllerDelegate: AnyObject {
    func didReceiveData(_ data: String)
}

class SecondViewController: UIViewController {
    weak var delegate: SecondViewControllerDelegate?
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func sendButtonTapped(_ sender: Any) {
        if let text = textField.text {
            delegate?.didReceiveData(text)
        }
        dismiss(animated: true, completion: nil)
    }
}

サンプルコードの説明

2-4行目:SecondViewControllerDelegateという名前のプロトコル(インターフェース)を定義しており、didReceiveDataメソッドを実装することを要求しています。
7行目:delegateという名前の変数を宣言しています。この変数は、SecondViewControllerDelegateプロトコルに準拠する任意のオブジェクトを参照するために使用されます。
15-17行目:textFieldtextプロパティからテキストを取得し、その値がnilでない場合に処理を続けるためのオプショナルバインディングを使用しています。
デリゲートオブジェクトが存在する場合(nilでない場合)、そのdidReceiveDataメソッドを呼び出して、入力されたテキストデータを渡しています。
dismissメソッドを使用して、SecondViewControllerを閉じています。これにより、このビューコントローラーが表示されているモーダルを閉じることができます。

ViewControllerの実装

サンプルコード

import UIKit

class ViewController: UIViewController, SecondViewControllerDelegate {
    
    @IBOutlet weak var displayLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        displayLabel.text = "次の画面で文字入力"
    }
    
    @IBAction func showSecondViewController(_ sender: Any) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        if let secondVC = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController {
            secondVC.delegate = self
            present(secondVC, animated: true, completion: nil)
        }
    }
    
    func didReceiveData(_ data: String) {
        displayLabel.text = data
    }
}

サンプルコードの説明

3行目:SecondViewControllerDelegateプロトコルに準拠しています。これにより、SecondViewControllerからのデータ受け取りを処理するためのdidReceiveDataメソッドを実装できるようになります。
13-16行目:ボタンタップした時に次の画面に遷移する処理
15行目:作成したsecondVCSecondViewControllerのインスタンス)のdelegateプロパティに自身(self)を設定しています。これにより、ViewControllerSecondViewControllerからのデリゲート呼び出しを受け取れるようになります。
20-22行目:SecondViewControllerDelegateプロトコルに定義されているdidReceiveDataメソッドを実装しています。このメソッドは、SecondViewControllerからデータ(テキスト)を受け取り、そのデータをdisplayLabelのテキストとして設定しています。

動作確認

ふくしま

それではビルドして動作確認してみましょう!

【Swift】画面間のデータ受け渡しをデリゲート(Delegate)やクロージャー(Closure)を使って実装する方法をサンプルコードを示しながら徹底解説!

クロージャーを使ったデータ受け渡しの実装方法

概要

デリゲートを使った実装をクロージャーを利用して実装していきましょう。
実際の開発では例えば以下のような場面で利用されます。

・WebサービスやAPIからデータを取得した際に、そのデータをUIコンポーネントに表示するために各画面やビューに渡す必要があります。

UI設計は、デリゲートと同様になります。

SecondViewControllerの実装

サンプルコード

import UIKit

class SecondViewController: UIViewController {
    var onComplete: ((String) -> Void)? // クロージャを保持する変数
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func sendButtonTapped(_ sender: Any) {
        if let text = textField.text, !text.isEmpty {
            onComplete?(text) // クロージャを実行してデータを渡す
        }
        dismiss(animated: true, completion: nil) // 画面を閉じる
    }
}

サンプルコードの説明

4行目:onCompleteという名前の変数が定義されています。この変数は、String型のパラメータを取り、Voidを返すクロージャ(関数)を保持するオプショナル変数です。これは、テキストデータを渡して実行するために他のクラスから設定されることを意図しています。
12-14行目:textFieldtextプロパティから取得したテキストが空でない場合、onCompleteクロージャが存在すればそれを呼び出し、そのテキストをパラメータとして渡します。これにより、SecondViewControllerからデータを渡す処理を実行します。
15行目:dismiss(animated:completion:)メソッドを呼び出して、SecondViewControllerを閉じます。これにより、モーダルで表示されているこのビューコントローラーがアニメーションを伴って閉じられ、前の画面に戻ります。

ViewControllerの実装

サンプルコード

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var displayLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        displayLabel.text = "次の画面で文字入力"
    }
    
    @IBAction func showSecondViewController(_ sender: Any) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        if let secondVC = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController {
            // クロージャを通じてデータを受け取る
            secondVC.onComplete = { [weak self] data in
                self?.displayLabel.text = data
            }
            present(secondVC, animated: true, completion: nil)
        }
    }
}

サンプルコードの説明

16-19行目:secondVConCompleteプロパティ(クロージャ)に、データ受け取り時の処理を定義しています。このクロージャ内で、displayLabelのテキストを更新します。[weak self]を使用することで、循環参照を避けています。
19行目:presentメソッドを使用して、secondVCをモーダルビューとして表示しています。animated: trueにより、遷移にアニメーションが適用されます。

動作確認

ふくしま

それではビルドして動作確認してみましょう!

【Swift】画面間のデータ受け渡しをデリゲート(Delegate)やクロージャー(Closure)を使って実装する方法をサンプルコードを示しながら徹底解説!

まとめ

いかがでしたか?
本記事では、デリゲートパターンやクロージャーを用いて、画面間のデータ受け渡しを行う方法を詳細に解説しました。開発シーンに合わせて、使い分けると良いでしょう。
それでは、この記事が皆様の開発ライフの一助になれれば幸いです!

ふくしま

この記事があなたのスキルアップに役立ったなら、次のキャリアステップを踏み出す絶好の機会かもしれません。エンジニアとしてのさらなる成長と挑戦を求めるなら、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
をオススメします!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次