意味不明の代表格Delegate
Swiftをやる上で意味不明の代表格 **デリゲート**について解説します。 まずは今回のテスト環境から説明します。 構成はこんな感じ。デフォルトのMain.storuboardの初期画面にViewオブジェクトを追加。
その ViewのクラスにCustomViewクラスを割り当てている。
CustomView.xivにはCustomView.swiftファイルが割り当てられている。
もちろん、Viewオブジェクトは、ViewController.swiftファイルから扱えるようにGUIで紐付けをして、
CustomView.swiftファイルにも,Buttomオブジェクトのタップを感知できるようにGUIで紐付けてある。
ここで2つのSwiftファイルを見てみましょう。
CustomView.swift
import UIKit
//①プロトコルを宣言
protocol testDelegate: class{
//②関数名と引数の型を定義
func tappedSendButton(text: String)
}
class CustomView: UIView {
var text = "これはCustomViewクラスのフィールド変数だよ"
//②デリゲートを宣言
weak var delegate: testDelegate?
//
@IBAction func tappedtTestButton(_ sender: Any) {
//④委任する関数を呼び出す。
delegate?.tappedSendButton(text: text)
}
//ここから下は、XivをViewに貼り付ける処理で今回のデリゲートの処理には関係ない
override init(frame: CGRect){
super.init(frame: frame)
self.configureView()
}
required init?(coder: NSCoder){
super.init(coder: coder)
self.configureView()
}
private func configureView(){
guard let view = self.loadViewFromNib(nibName:"CustomView") else {
return
}
view.frame = self.bounds
self.addSubview(view)
}
}
ViewController.swift
import UIKit
//testDelegateプロトコルを継承
class ViewController: UIViewController, testDelegate {
@IBOutlet weak var testView: CustomView!
//④で呼び出された関数がViewControllerに委任されてるためtappedSendButton関数が呼び出される
func tappedSendButton(text: String) {
print(text)
}
override func viewDidLoad() {
super.viewDidLoad()
testViewオブジェクトの処理を自分自身(ViewController)に委任しますと宣言する。
testView.delegate = self
}
}
ボタンをタップすると
consoleに
これはCustomViewクラスのフィールド変数だよ
と表示される
デリゲートとはつまり
あるクラス(今回はController.swift)から、あるクラス(CustomView.swift)の関数を呼び出したい時に使う。
今回でいえば、ボタンがタップされたかどうかはCustomView.swiftでしか感知できないが、そこにデリゲートを追加してController.swiftに紐付いた関数を用意することでボタンがタップされた時に呼び出される関数から
ControllerクラスのtappedSendButtonを呼び出すと言うことになる。
@IBAction func tappedtTestButton(_ sender: Any) {
//ControllerクラスのtappedSendButton関数を呼び出す。
delegate?.tappedSendButton(text: text)
}
デリゲートのメリット
勘のいい人ならわかると思うがデリゲートも最大のメリットは
クラス間で変数を自由に受け渡しができること
関数を呼ぶタイミングを任意のタイミングに調整できること
だと思う。今回の場合で言えばもしCustomView.swiftで
テキストフィールドを持っていたら、ボタンが押された瞬間のテキストフィールドをViewControllerに送る事ができる。
しかも、ボタンが押された瞬間と言う任意のタイミングで。
まとめ
デリゲートとは関数の処理を他のクラスの関数に委任することなんだな。
書き方についてはこう言う風に書くんだな。と覚えましょう。
(書き方が難しすぎるからややこしくなってるだけ)