質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Delegates

Delegatesとは、オブジェクト指向型プログラミングにおいて、あるオブジェクトの操作を一部の他のオブジェクトに代替させる手法のこと。オブジェクトは他のデリゲートに頼って関数を実行することができます。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

6334閲覧

SwiftでViewController間のdelegateをする方法

pascal1623

総合スコア18

Delegates

Delegatesとは、オブジェクト指向型プログラミングにおいて、あるオブジェクトの操作を一部の他のオブジェクトに代替させる手法のこと。オブジェクトは他のデリゲートに頼って関数を実行することができます。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2017/12/06 11:23

###前提・実現したいこと
SwiftでViewController間でdelegateをしようと思ってるいるのですが、うまく行きません。

コードでは、SecondViewController上のボタンを押すと、FirstViewControllerのtest()が実行されるようにしようとしています。

###発生している問題・エラーメッセージ
SecondViewControllerでのdelegateがnilになってしまい、FirstViewControllerにあるtest()を呼んでくれません。

###該当のソースコード

Swift

1//FirstViewController 2import UIKit 3 4class FirstViewController: UIViewController, TestDelegate { 5 6 func test() { 7 print("called delegate") 8 } 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 13 let storyboard = UIStoryboard(name: "Main", bundle: nil) 14 let secondVC = storyboard.instantiateViewController(withIdentifier: "Second") as! SecondViewController 15 16 secondVC.delegate = self 17 } 18 19 override func didReceiveMemoryWarning() { 20 super.didReceiveMemoryWarning() 21 } 22} 23 24//SecondViewController 25import UIKit 26 27protocol TestDelegate { 28 func test() 29} 30 31class SecondViewController: UIViewController { 32 33 var delegate:TestDelegate? 34 35 @IBAction func pushButton(_ sender: UIButton) { 36 delegate?.test() 37 } 38 39 override func viewDidLoad() { 40 super.viewDidLoad() 41 } 42 43 override func didReceiveMemoryWarning() { 44 super.didReceiveMemoryWarning() 45 } 46}

###試したこと
昨日、ViewからViewControllerへのdelegateを質問した際に、ViewControllerで指定したViewのインスタンスが正しくstoryboard上のViewをさしていないという指摘をいただきました。

そのため、FirstViewControllerからStoryboard上のSecondViewControllerを示すようにコードを書いてみたつもりなのですが、やはりインスタンスを正しく指定できていないのか、SecondViewControllerのdelegateがnilとなっています。

###補足情報(言語/FW/ツール等のバージョンなど)
StoryBoardはMain.storyboardです。
SecondViewControllerのstoryboard IDは"Second"としています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

FirstViewからSecondViewへの遷移方法がコードからは読み取れないので予想になってしまいますが、
おそらくSecondViewのインスタンスが都度作成されちゃってるんだと思います。
あと、viewDidLoad()内でViewをインスタンスするようなコードは書かない方が無難です。
参考にセグエを使ったFirstViewController.swiftを載せときます。

swift

1 2import UIKit 3 4class FirstViewController: UIViewController, TestDelegate { 5 6 func test() { 7 print("called delegate") 8 } 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 } 13 14 override func didReceiveMemoryWarning() { 15 super.didReceiveMemoryWarning() 16 } 17 18 override func viewDidAppear(_ animated: Bool) { 19 performSegue(withIdentifier: "next", sender: nil) 20 } 21 22 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 23 let secondVC = segue.destination as? SecondViewController 24 secondVC?.delegate = self 25 } 26 27}

2017.12.7 追記

TabBarのインスタンス経由でFirstViewControllerのインスタンスを取得
(FirstViewControllerがイニシャルビューと仮定してます)

swift

1 2// FirstViewController.swift 3import UIKit 4 5class FirstViewController: UIViewController, TestDelegate { 6 7 func test() { 8 print("called delegate") 9 } 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 } 15 16 override func didReceiveMemoryWarning() { 17 super.didReceiveMemoryWarning() 18 } 19} 20 21// SecondViewController.swift 22import UIKit 23 24protocol TestDelegate { 25 func test() 26} 27 28class SecondViewController: UIViewController { 29 30 var delegate:TestDelegate? 31 32 @IBAction func pushButton(_ sender: UIButton) { 33 delegate?.test() 34 35 } 36 37 override func viewDidLoad() { 38 super.viewDidLoad() 39 40 // TabBarのインスタンス経由でFirstViewControllerのインスタンスを取得 41 if let tabvc = UIApplication.shared.keyWindow?.rootViewController as? UITabBarController { 42 // FirstViewControllerのインスタンスをdelegateにセット 43 self.delegate = tabvc.viewControllers?.first as? TestDelegate 44 } 45 46 } 47 48 override func didReceiveMemoryWarning() { 49 super.didReceiveMemoryWarning() 50 } 51}

投稿2017/12/06 13:10

編集2017/12/07 02:33
fromageblanc

総合スコア2724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pascal1623

2017/12/06 13:26

遷移の仕方も問題になるのですね。説明不足で申し訳ありません。 FirstViewControllerとSecondViewControllerはTabBarで切り替えるように作っています。 そもそも作りたいアプリの中でつまづいているのがTabBarで切り替えるViewController同士でdelegateをしたいという部分です。 まだまだインスタンスの生成についてよく理解していないと思うのですが、TabBarでは生成されたインスタンスの表示を切り替えているだけだと思っておりました。
pascal1623

2017/12/07 13:58

ありがとうございます。 この方法でうまく行くことを確認させていただきました。 もしよろしけばもう少し教えていただきたいのですが、 tabbarで管理しているどのViewController同士でもdelegateできるようにしたいと思っています。 SecondViewContorollerに if let tabvc = UIApplication.shared.keyWindow?.rootViewController as? UITabBarController { let firstVC = tabvc.viewControllers?[0] self.delegate = firstVC as? TestDelegate と書いたところ、やはりdelegateが呼ばれます。 しかし、FirstViewControllerに if let tabvc = UIApplication.shared.keyWindow?.rootViewController as? UITabBarController { secondVC = tabvc.viewControllers?[1] as? SecondViewController secondVC?.delegate = self と書いてもdelegateが設定されません。 また元々の記載では、なぜダメなのかもよくわからずなんともすっきりしません。 大変申し訳ありませんが教えていただけましたら助かります。
fromageblanc

2017/12/07 14:25

viewDidLoad内に書いちゃうと一度しか実行されないので、viewDidAppearに移してください override func viewDidAppear(_ animated: Bool) { if let tabvc = UIApplication.shared.keyWindow?.rootViewController as? UITabBarController { let secondVC = tabvc.viewControllers?[1] as? SecondViewController secondVC?.delegate = self } }
pascal1623

2017/12/08 11:01

本当ですね!! これでdelegateが呼ばれました! 正直、まだ理解できていないことも多いのですが、今回教えてもらったことを参考に精進させていただきます。 本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問