画面の遷移 (モーダル表示) と画面間のデータ受渡し
ここではボタンを押したときに、次の画面を表示します。その時に、元の画面のテキストフィールドに入力した文字を、 現れる画面に渡して表示します。
ストーリーボードでは次のようにしています。
ユーザーインターフェイスの準備としては、画面の通り、最初の画面にテキストフィールド (UITextField) とボタン (UIButton) を一つずつ配置します。 二番目の画面にはラベル (UILabel) とボタン (UIButton) をおきます。
ボタンから次の画面へセグウェイ (segue) を設定して、新しく表示されるオレンジ色の画面をモーダル表示しています。
セグウェイの設定方法は、次のビデオのようにボタンから ⌃ control ドラッグ (または右ドラッグ) して、コンテキストメニューから Present Modally を選択します。
セグウェイを作成したら、識別子 (identifier) を設定しておきます。ここでは showView2 という識別子にしておきます。
最初の画面のビューコントローラクラスを ViewController1、二番目の画面のビューコントローラクラスを ViewController2 とします。
次の画面にデータを渡す
セグウェイの実行時に prepare(for:sender:) が呼ばれますが、ここで、セグウェイの参照が取得できます。 segue の destination プロパティから、これから表示するビューコントローラが取得できます。
このビューコントローラにデータを渡すことで、次の画面へデータを渡すことができます。
... override func prepare( for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "showView2" { let vc = segue.destination as! ViewController2 vc.text = textField.text ?? "" } }
ちなみに、prepare(for:sender:)のタイミングでは、新しい画面のビューおよびそのサブビューはまだ作成されていませんので、 ビューに直接値を渡すことはできません。
このため、ビューに直接値をセットするのではなく、ビューコントローラにプロパティ等を作成しておき、そこにデータをセットします。
新しい画面のビューコントローラ (ここでは ViewController2) の viewDidLoad でビューに値をセットすれば、 渡された値を画面に表示することができます。
... var text : String = "" @IBOutlet weak var label1: UILabel! override func viewDidLoad() { super.viewDidLoad() label1.text = text } ...
モーダル表示された画面は dismiss(animated:completion:) メソッドを呼ぶことで閉じます。ここでは Close ボタンのアクションで dismiss を呼び出しています。
@IBAction func closeTapped(_ sender: Any) { dismiss(animated: true, completion: nil) }
全体のコードを以下に示します。
ViewController1.swift
import UIKit class ViewController1: UIViewController { @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() } override func shouldPerformSegue( withIdentifier identifier: String, sender: Any?) -> Bool { if identifier == "showView2" { if let text = textField.text, !text.trimmingCharacters(in: .whitespaces).isEmpty { return true } } return false } override func prepare( for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "showView2" { let vc = segue.destination as! ViewController2 vc.text = textField.text ?? "" } } }
shouldPerformSegue ではテキストフィールドの入力検証を行って、何も入力されていない (もしくは空白文字のみ) 場合に、 セグウェイが実行されないようにしています。
ViewController2.swift
import UIKit class ViewController2: UIViewController { var text : String = "" @IBOutlet weak var label1: UILabel! override func viewDidLoad() { super.viewDidLoad() label1.text = text } @IBAction func closeTapped(_ sender: Any) { dismiss(animated: true, completion: nil) } }
なお、セグウェイの設定で明示的に Modal 表示を選択した場合は、トランジションの設定や表示設定 (Presentation) を指定することができます。 デフォルトではモーダル画面の表示アニメーションは下からせり上がり、フルスクリーンで表示されます。