こんにちは!株式会社メモリアインクのふくしまです!
この記事では、Swiftにおける画面間のデータの受け渡しをデリゲートやクロージャーを利用して実装する方法をサンプルコードを示しながら解説していきます。
この記事を読んで分かること…
・デリゲート(delegate)を使った画面間のデータ受け渡し方法
・クロージャーを使った画面間のデータ受け渡し方法
デリゲートやクロージャーについて知らないよって方は、以下の記事で詳しく解説していますので、併せてご確認ください!
デリゲートを使ったデータ受け渡しの実装方法
概要
遷移先の画面のテキストフィールドに入力した文字を、遷移元の画面に表示する実装を例に解説します。
実際の開発では例えば以下のような場面で利用されます。
- ユーザーがアイテムを選択した際に、そのアイテムの詳細情報を表示する画面にデータを渡す。
- フォーム画面から、ユーザーが入力した情報を確認画面や結果表示画面に渡す。
UI設計
遷移先の画面(SecondViewController)
・遷移元の画面に受け渡すデータ入力のためのUITextField
・遷移元へデータを受け渡すためのボタンUIButton
遷移元の画面(ViewController)
・遷移先で入力した文字を表示するためのテキストUILabel
・次画面へ遷移するためのボタンUIButton
画面遷移については以下の記事で解説していますので、併せてご覧ください!
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行目:textField
のtext
プロパティからテキストを取得し、その値が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行目:作成したsecondVC
(SecondViewController
のインスタンス)のdelegate
プロパティに自身(self
)を設定しています。これにより、ViewController
がSecondViewController
からのデリゲート呼び出しを受け取れるようになります。
・20-22行目:SecondViewControllerDelegate
プロトコルに定義されているdidReceiveData
メソッドを実装しています。このメソッドは、SecondViewController
からデータ(テキスト)を受け取り、そのデータをdisplayLabel
のテキストとして設定しています。
動作確認
それではビルドして動作確認してみましょう!
クロージャーを使ったデータ受け渡しの実装方法
概要
デリゲートを使った実装をクロージャーを利用して実装していきましょう。
実際の開発では例えば以下のような場面で利用されます。
・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行目:textField
のtext
プロパティから取得したテキストが空でない場合、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行目:secondVC
のonComplete
プロパティ(クロージャ)に、データ受け取り時の処理を定義しています。このクロージャ内で、displayLabel
のテキストを更新します。[weak self]
を使用することで、循環参照を避けています。
・19行目:present
メソッドを使用して、secondVC
をモーダルビューとして表示しています。animated: true
により、遷移にアニメーションが適用されます。
動作確認
それではビルドして動作確認してみましょう!
まとめ
いかがでしたか?
本記事では、デリゲートパターンやクロージャーを用いて、画面間のデータ受け渡しを行う方法を詳細に解説しました。開発シーンに合わせて、使い分けると良いでしょう。
それでは、この記事が皆様の開発ライフの一助になれれば幸いです!
この記事があなたのスキルアップに役立ったなら、次のキャリアステップを踏み出す絶好の機会かもしれません。エンジニアとしてのさらなる成長と挑戦を求めるなら、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
コメント