##概要
ViewController
のUITextField
にテキストを入力しUIButton
をタップすると、その内容がLabelViewController
のUILabel
に表示される。SegueはStoryboard上で生成。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
var text: String = ""
override func viewDidLoad() {
super.viewDidLoad()
}
// ボタンが押された時
@IBAction func tapButton(_ sender: UIButton) {
print("tapButton内の処理")
self.text = "入力:"
performSegue(withIdentifier: "toLabelViewController", sender: nil)
print("セグエが呼ばれました")
}
// Segueの準備
override func prepare(for segue: UIStoryboardSegue, sender: Any!) {
if (segue.identifier == "toLabelViewController") {
let next: LabelViewController = (segue.destination as? LabelViewController)!
next.text = self.text + textField.text!
print("遷移先にテキストを受け渡す")
}
}
// 戻るボタンにより前画面へ遷移
@IBAction func back(segue: UIStoryboardSegue) {
print("back")
}
}
import UIKit
class LabelViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var text: String!
override func viewDidLoad() {
super.viewDidLoad()
label.text = text
print("ラベルのテキストを変更")
}
}
##問題点
#####ラベルに表示されるテキスト
期待する結果:入力:{テキストフィールドに入力された内容}
実行結果:{テキストフィールドに入力された内容}
このように"入力:"
の部分が表示されない。Segueは呼び出されているはずなのに、tapButton()
内の処理が行われていないという訳のわからない状態に陥ったためログを取って確認してみた。
#####ボタンタップ後の処理の流れ
- 遷移先にテキストを受け渡す
- ラベルのテキストを変更
- tapButton内の処理
- 遷移先にテキストを受け渡す
- セグエが呼ばれました
どうやらperformSegue()
を宣言する前にSegueが呼び出されデータの受け渡しを行われているようだ。さらにLabelViewController
のviewDidLoad()
が実行された後でtapButton()
内の処理が行なわれている。ここでのperformSegue()
によって再度データの受け渡しが行われたところで処理が終わり画面が遷移する。(ちなみに4.遷移先にテキストを受け渡す
の後で警告メッセージが表示されていた。)
######警告メッセージ
SegueOnStoryboard[64302:4946416] <UIView: 0x7fb10cf0c750; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x61000023bec0>>'s window is not equal to <SegueOnStoryboard.LabelViewController: 0x7fb10ac22230>'s view's window!
#####問題の解決
ここまで来てもよく分からない。Storyboardに問題があるのではと思い少しいじってみた。
Segueを生成する際にUIButton
からLabelViewController
に矢印を引っ張っていたが、ViewController
からLabelViewController
へのSegueに変更した結果、問題が解消できた。
UIButton
から Segueを生成すると、タップされたタイミングで自動的にSegueが呼ばれ、その後tapButton()
内の処理が行われる。考えてみれば当然だが、この場合はコードで Segueを呼び出す必要がなくなるため、今回のような重複処理を招いた。
Storyboardで生成したSegueを扱うときは、つなぐ元と先をしっかりと意識した上でコードを書くことが必要であると反省。