Edited at

[Swift 5] Protocolを使ったDelegateの実装方法の例

いつも使うときに忘れてしまう、protocolを使ったDelegateの実装方法をメモしておきます。

ParentとChildの関係のように、一方が他方のインスタンスを生成するなどして知っている時に使う方法です。

なので、お互いを知らない遠いViewController同士での指示等には使えません。

(勘違いありましたら、お教えください)


まずは肝要のDelegateをprotocolで定義します。


Protocol.swift

protocol MessageDelegate: AnyObject {

func sendMessage(_ message: String)
}



  1. AnyObjectに適合することで、classでしか使えなくなります。

  2. メソッドの引数には送りたいものを入れて渡せるようにしましょう。

ここでは仮にmessageという文字列を引き渡すこととします。


「お〜い、〇〇して〜!」と指示を送りたい側の定義


ChildViewController.swift

final class ChildViewController {

weak var messageDelegate: MessageDelegate?

@IBAction func didTapSendButton(_ sender: UIButton) {
messageDelegate?.sendMessage("Childからメッセージ送信")
}
}




  1. weak(弱参照)かつOptionalDelegateを宣言します。

  2. 送りたいタイミングの場所でDelegateのメソッドを呼び出します。

  3. ここでは、「Childからメッセージ送信」という文字列を引数で渡しています。

ここでは、StoryboardとOutlet接続してあるSendButtonが押されたタイミングとしています。


「分かった!やったるよ!」と指示を受け取る側の定義


ParentViewController.swift

final class ParentViewController {

// ParentからChildに遷移するためにViewControllerのインスタンスを生成
let vc = UIStoryboard(name: "child", bundle: nil)
.instantiateInitialViewController() as! ChildViewController
// このタイミングで、ChildViewControllerで宣言してある`MessageDelegate`に自ら(Parent)を代入
vc.MessageDelegate = self // 「俺に任せろ!!」の意
navigationController.pushViewController(vc, animated: true)
}

インスタンスを作成する時にDelegateに自らをセット


ParentViewController.swift

// ParentViewControllerでMessageDelegateに適合します。

extension ParentViewController: MessageDelegate {
// `sendMessage`メソッドを実装します(Xcodeからも「必須だよ」と教えてくれます)
func sendMessage(message: String) {
// 引数のmessageにはChildで入力した「Childからメッセージ送信」という文字列が入ってきます。
print(message) // コンソールに「Childからメッセージ送信」と出力される。
}
}

指示を受けたら行いたい処理を書く。

この場合は、Childから受け取ったメッセージを出力しているだけですが、色々任せられますね。

以上、これで次にDelegate実装する時にも迷わない…