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

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

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

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

Q&A

解決済

1回答

745閲覧

クロージャーを用いた値渡しがうまくいかない

KCROW

総合スコア7

Swift

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

0グッド

0クリップ

投稿2021/05/28 22:33

Closureを理解するため、簡単なサンプルを作成中です。

FirstViewControllerのnextButtonでSecondViewControllerへ画面遷移

SecondViewControllerのcountButtunを押すと数字が足されてcountLabelに反映

SecondViewControllerのaddButtonでFirstViewControllerに戻る

この挙動でcountLabel(SecondViewController)の値をクロージャーを用いて
label(FirstViewController)に渡したいのですがうまくいきません。

FirstViewController

1import UIKit 2 3class FirstViewController: UIViewController { 4 5 let second = SecondViewController() 6 7 @IBOutlet weak var label: UILabel!{ 8 didSet{ 9 label.text = "0" 10 11 } 12 } 13 14 15 @IBAction func nextButton(_ sender: UIButton) { 16 17 let secondStoryboard = UIStoryboard(name: "Second", bundle: nil) 18 let secondVC = secondStoryboard.instantiateInitialViewController() as!SecondViewController 19 20 let nav = self.navigationController! 21 nav.pushViewController(secondVC, animated: true) 22 second.tap { CountModel in 23 print("ーーーー渡されたよーーーーーーー") 24 self.label.text = CountModel.count.description 25 } 26 27 28 } 29 30 override func viewDidLoad() { 31 super.viewDidLoad() 32 33 } 34 35} 36

SecondViewController

1import UIKit 2 3class SecondViewController: UIViewController{ 4 5 6 private var countmodel = CountModel.init(count: 0) 7 8 @IBOutlet weak var countLabel: UILabel!{ 9 didSet{ 10 countLabel.text = countmodel.count.description 11 } 12 } 13 14 @IBAction func countButtun(_ sender: UIButton) { 15 countmodel.count = countmodel.count + 1 16 countLabel.text = countmodel.count.description 17 print(countmodel) 18 } 19 20 21 @IBAction func addButton(_ sender: Any) { 22 tap() 23 self.navigationController?.popViewController(animated: true) 24 25 } 26 27 //クロージャー関数 28 func tap(completion:((CountModel)->Void)? = nil){ 29 print("tapしたよ") 30 print(countmodel) 31 completion?(CountModel(count: countmodel.count)) 32 } 33 34 override func viewDidLoad() { 35 super.viewDidLoad() 36 37 } 38 39 40 } 41

CountModel

1import Foundation 2 3struct CountModel { 4 var count:Int 5} 6

以上がコードです。

playground上での簡単なクロージャーのサンプルは理解できるのですが
実際に非同期処理でなぜ値が渡らないかが分かりません。

どなたかよろしくお願いいたします。

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

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

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

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

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

tomato879241

2021/05/29 01:17

>非同期処理でなぜ値が渡らないかが分かりません 「非同期処理」とはどういう意味でしょうか? ただSecondViewControllerにprotocolをつけて、値をdelegateを通してFirstViewControllerに渡せばいいのでは?
guest

回答1

0

ベストアンサー

やりたいことはたぶんこういうことかと。なお、これは「非同期処理」ではなく、「コールバック」ですね。

FirstViewController.swift

  • SecondViewController は storyboard から生成するので、直接生成しても意味はありません。
  • second.tap をここで呼ぶと、画面遷移する直前にタップした時の動作を行うことになります。
    代わりに、secondVC の callback を設定すると良いのでは。
  • nav.pushViewController は secondVC の準備ができてからの方が良い気がします。

diff

1 class FirstViewController: UIViewController { 2 3- let second = SecondViewController() 4 5 // 略 6 7 @IBAction func nextButton(_ sender: UIButton) { 8 let secondStoryboard = UIStoryboard(name: "Second", bundle: nil) 9 let secondVC = secondStoryboard.instantiateInitialViewController() as!SecondViewController 10 11- let nav = self.navigationController! 12- nav.pushViewController(secondVC, animated: true) 13- second.tap { CountModel in 14+ secondVC.callback = { CountModel in 15 print("ーーーー渡されたよーーーーーーー") 16 self.label.text = CountModel.count.description 17 } 18 19+ let nav = self.navigationController! 20+ nav.pushViewController(secondVC, animated: true) 21 }

SecondViewController.swift

  • コールバック関数 callback をプロパティに持つ必要があります。
  • tap メソッドでは、コールバック関数を引数に取るのではなく、事前に設定された callback を呼びましょう。

diff

1 class SecondViewController: UIViewController{ 2 3 private var countmodel = CountModel.init(count: 0) 4 5+ var callback: ((CountModel) -> Void)? 6 7 // 略 8 9- //クロージャー関数 10- func tap(completion:((CountModel)->Void)? = nil){ 11+ func tap() { 12 print("tapしたよ") 13 print(countmodel) 14- completion?(CountModel(count: countmodel.count)) 15+ callback?(countmodel) 16 }

投稿2021/05/29 05:16

hoshi-takanori

総合スコア7895

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

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

KCROW

2021/05/29 12:17

ご回答ありがとうございます!やりたかったことができました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問