2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Storyboardで生成したSegue(セグエ)をコードで呼び出すときの注意

Last updated at Posted at 2016-10-06

##概要
ViewControllerUITextFieldにテキストを入力しUIButtonをタップすると、その内容がLabelViewControllerUILabelに表示される。SegueはStoryboard上で生成。

ViewController.swift
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")
    }

}
LabelViewController.swift
import UIKit

class LabelViewController: UIViewController {
    
    @IBOutlet weak var label: UILabel!
    
    var text: String!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        label.text = text
        print("ラベルのテキストを変更")
        
    }

}

##問題点
#####ラベルに表示されるテキスト
期待する結果:入力:{テキストフィールドに入力された内容}
実行結果:{テキストフィールドに入力された内容}

このように"入力:"の部分が表示されない。Segueは呼び出されているはずなのに、tapButton()内の処理が行われていないという訳のわからない状態に陥ったためログを取って確認してみた。

#####ボタンタップ後の処理の流れ

  1. 遷移先にテキストを受け渡す
  2. ラベルのテキストを変更
  3. tapButton内の処理
  4. 遷移先にテキストを受け渡す
  5. セグエが呼ばれました

どうやらperformSegue()を宣言する前にSegueが呼び出されデータの受け渡しを行われているようだ。さらにLabelViewControllerviewDidLoad()が実行された後で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を扱うときは、つなぐ元と先をしっかりと意識した上でコードを書くことが必要であると反省。

2
4
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?