Edited at

Swiftでデリゲートによる画面間での値の受け渡し

More than 3 years have passed since last update.

以前作成したのObjective-CのプロジェクトをSwiftに書き直していたらdelegateによる画面間の値の受け渡し部分の書き方が若干異なったので修正をメモ。

基本的にはObjective-Cと同様です。


目的

StoryBoardで作成した画面Aと画面Bでのシンプルな値のやりとり。

ここでは、値を送る画面のクラスをSenderViewController、値を受け取る画面をReceiverViewControllerとし、NSString型のmessageを送っています。

左:受け取る画面,右:送る画面 をsegueで接続


値を送る画面クラス

まずは値を送る画面です。

値をやりとりするためのデリゲートとデリゲートメソッドを使用を先に宣言します。

ここでは、メッセージを受信するreceiveMessage()とoptinalReceiveMessage()を作成しました。

前者のメソッドは、受け取る側で必ず実装しないといけないメソッドであり実装しないとエラーとなります。

一方後者のoptinalなメソッドの実装は任意となり実装しなくても構いません。

senderViewControllerは単純なクラスでsendeMessage()を利用し、それぞれメッセージを送っています。


SenderViewController.swift


//protocolを定義
//値を渡すために使うメソッドを宣言します
@objc protocol senderDelegate{
func receiveMessage(message:NSString)
optional func optinalReceiveMessage(message:NSString)
}

class SenderViewController: UIViewController{
weak var delegate :SenderDelegate?
let message = "you got a message"
let optMessage = "you got a optinal message"

func sendMessage(sender: AnyObject) {
delegate?.receiveMessage(message)
delegate?.optionalReceiveMessage!(optMessage)
}
}



値を受け取る画面クラス

画面を受け取る画面では、SenderViewControllerクラスを作成したSenderDelegateを宣言しています。

また、prepareForSegueを画面遷移時にインスタンスを生成しデリゲートをセットしています。


ReceierViewController.swift

class ReceiverViewController: UIViewController,SenderDelegate {

//画面遷移時に呼ばれる
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

//segueのidentifierを特定
//今回は画面間のsegueを"messageSegue"
if segue.identifier == "messageSegue" {
var senderViewController:SenderViewController = segue.destinationViewController as SenderViewController
senderViewController.delegate = self
      }
}
}


StoryBoardのUtilitiesでIdentifierを設定

そして、同クラス内でSenderViewControllerで宣言したデリートメソッドを実装します。

これで、SenderViewControllerからsendMessage()を呼べがReceiverViewControllerにmessageが送られます。


ReceierViewController.swift


func receiveMessage(message: NSString) {
println(message)
}
func optionalReceiveMessage(message: NSString) {
println(message)
}

また、値を渡しそのままSenderViewControllerを閉じたいときは、デリゲートメソッド内で、dismissViewControllerAnimated()が利用できます。

ほぼObjective-Cのときと同じく書け、値を受け渡しが簡単に行えました。

未実装のoptionalなデリゲートメソッドを呼ぼうとするとメソッドの実装の判定からメソッド自体が呼ばれないようです。

!で強制的に呼ぶと例外が発生し止まります。

11/19修正