複数のViewControllerの間でデータをやり取りしたい時があります。
例えば以下のアプリのようにTableViewでタッチされたお店を、地図上のピンで選択する時です。
このように異なるViewの間でデータをやり取りするにはSwiftのdelegateを使うと実装できます。
ピンを選択する機能はMapViewでないとできません。
しかし、Delegateを使うとピンを選択する機能をTableViewに与えることができます。
そうすれば、TableViewで選択された情報をもとにピンを選択することができます。

MapViewのコントローラをMapVC、
TableViewのコントローラをSemiModalVCとして説明していきます。
プロトコル
まずはプロトコルを作成します。
MapVCの中に以下を記載します。
1 2 3 |
protocol RestMapDelegate { func selectAnnotation(index:Int) } |
プロトコルで定める関数はピンを選択する機能です。
プロトコルに批准する
上記のプロトコルをMapVCで批准し、ピンを選択する処理を実装します。
1 2 3 4 5 6 7 |
class MapVC: UIViewController, MKMapViewDelegate, FloatingPanelControllerDelegate,RestMapDelegate{ func selectAnnotation(index: Int) { dispMap.selectAnnotation(annotations[index], animated: true) } } |
delegate変数を追加する
SemiModalVCの中にdelegate変数を追加します。
1 2 3 |
class SemiModalVC: UIViewController, UITableViewDelegate, UITableViewDataSource { var delegate:RestMapDelegate? } |
ViewController同志をdelegateで結びつける
SemiModalVCとMapVCを結びつけます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
var fpc:FloatingPanelController! func showSemiModal(restList:[Restaurant]){ fpc = FloatingPanelController() fpc.delegate = self fpc.surfaceView.cornerRadius = 24.0 guard let vc = self.storyboard?.instantiateViewController(withIdentifier: "fpc") as? SemiModalVC else { return } vc.restList = restList vc.delegate = self fpc.set(contentViewController: vc) fpc.addPanel(toParent: self) } |
SemiModalVCをインスタンス化して、プロパティであるdelegateにMapVC自身を設定します。
テーブルが選択された時にピンを選択する
1 2 3 |
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { delegate?.selectAnnotation(index: indexPath.row) } |
こんな感じでVC間のやり取りはDelegateを使うと便利です。