画面の遷移 (モーダル表示) と画面間のデータ受渡し

ここではボタンを押したときに、次の画面を表示します。その時に、元の画面のテキストフィールドに入力した文字を、 現れる画面に渡して表示します。

ストーリーボードでは次のようにしています。

ユーザーインターフェイスの準備としては、画面の通り、最初の画面にテキストフィールド (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) を指定することができます。 デフォルトではモーダル画面の表示アニメーションは下からせり上がり、フルスクリーンで表示されます。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Swift による iOS 開発入門