【Xcode】モーダル表示で遷移先へ値を渡す時のハマりポイント

公開日: : iPhoneアプリ開発

20160210-140020.jpg

モーダル表示で遷移先の画面へ値を渡す際、最初はハマりやすいポイントについて解説したいと思います。

    

スポンサード リンク

例えば、以下のような画面遷移を考えたとします。

20160210-140327.jpg

1つ目の画面でテキストフィールドに文字を入力してボタンを押すと、モーダル表示で次の画面に遷移し、入力した文字がラベルに表示されるという動きです。

    

1つ目の画面では、prepareForSegueで次の画面に入力テキストを受け渡します。

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        guard let second = segue.destinationViewController as? SecondViewController else {
            return
        }

        guard let text = self.textField.text else {
            return
        }
        
        second.text = text
    }
}

    

そして2つ目の画面ではviewDidLoadにて、前の画面から受け渡されてきた入力テキストをラベルに表示します。

class SecondViewController: UIViewController {
    
    var text : String = ""

    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.label.text = text
    }
}

    

これでうまく動きそうですが、実行してみると2つ目の画面のラベルに何も表示されません。

なぜでしょうか?

    

1つ目の画面のprepareForSegueに以下のコードを追加してみましょう。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    
    // 追加。destinationViewControllerの中身の型を調べる
    print("type = \(segue.destinationViewController.dynamicType)")
    
    guard let second = segue.destinationViewController as? SecondViewController else {
        return
    }

    guard let text = self.textField.text else {
        return
    }
    
    second.text = text
}

    

ちなみにdynamicTypeを使うと、インスタンスが実際に属するクラスを表すオブジェクトを得ることができます。

インスタンスに対してdynamicTypeという問い合わせを行うと、実際に属するクラスを表すオブジェクト(便宜的にクラスオブジェクトと呼びます)を値として得ることができます。

引用元 : 詳解 Swift 改訂版

    

そして再び実行すると、1つ目の画面でボタンをタップした際に以下のような出力がなされます。

type = UINavigationController

なんと、destinationViewControllerの中身がSecondViewControllerではなくてUINavigationControllerになっています!

    

これは何故かというと、1つ目の画面からUINavigationControllerに対してセグエを接続しているからなんですね。

20160210-142431.jpg

だから最初の

guard let second = segue.destinationViewController as? SecondViewController else {
    return
}

でas?によるダウンキャストに失敗して、次の画面にデータが受け渡されなかったわけです。

    

なので、1つ目の画面のprepareForSegueでは

  • まずセグエで接続されているUINavigationControllerを取得する
  • 次に、UINavigationControllerにぶら下がっているSecondViewControllerを取得する

という2段階の手順を踏まなければならないわけです。

これに従ってコードを書いてみましょう。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    
    // まずセグエで接続されているUINavigationControllerを取得する
    guard let nav = segue.destinationViewController as? UINavigationController else {
        return
    }
    
    // UINavigationControllerにぶら下がっているSecondViewControllerを取得する
    guard let second = nav.topViewController as? SecondViewController else {
        return
    }

    guard let text = self.textField.text else {
        return
    }
    
    second.text = text
}

これで無事、2つ目の画面に入力テキストが表示されるようになります!

    

@akio0911はこう思った。

今日解説した部分は、入門書などを読みながら学習していく過程でハマりやすいポイントの1つだと思います。

    

ちなみに解説の中で出てきた「guard」「as?」などについては、以下の本が詳しいです!

この記事が気に入ったら「いいね!」しよう

follow us in feedly

Feedlyで最新記事を購読

Twitterで更新情報をゲット!

LINEでご感想・ご要望お送りください!
(スマホでLINEを起動 > 友だち追加 > QRコード)

関連記事

I20160118-223109.jpg

Swift 2でシングルトンを初期化・呼び出しする方法

Swift 2でシングルトンを実装する方法について解説したいと思います! (※「シングルトンを

記事を読む

I20160207-111059.jpg

【Swift】Xcodeで型推論された変数や定数の型を調べる方法

Swiftには、そのデータ型が明らかであれば型を明記する必要が無い「型推論」という機能があります

記事を読む

I20160513-010707.jpg

Swiftで計算型プロパティをネストさせてみる

Swiftの計算型プロパティ(Computed property、コンピューテッドプロパティ)を

記事を読む

I20150802-085831.jpg

Swift 1.2でtouchesBeganメソッドのNSSetがSetへ変更されました

Swift 1.2で、touchesBegan・touchesMoved・touchesCanc

記事を読む

I20151201-120520.jpg

【Swift 2】switch内にてguardでbreakする

Swift 2のguard内ではreturnしないと文法エラーとなりますが、実はswitch

記事を読む

I20160925-163452.jpg

タブバーアイコン非選択時の色を変更する方法【iOS 10】

UITabBarControllerで、タブバーアイコン非選択時の色を変更する方法を紹介します!

記事を読む

20160423-124300.jpg

【RxSwift】Hot変換オペレータの1つであるshareReplayを使ってみる

最近、RxSwiftについて勉強中です。 今回は、Hot変換オペレータの1つであるshareR

記事を読む

20140818-141439.jpg

iPhoneアプリを作りたい開発初心者にまずはやってみて欲しい3つのこと

今日は、これからiPhoneアプリを作りたい開発初心者の方にやってもらいたいことを書いてみた

記事を読む

I20160228-162014.jpg

詳解 Swift 改訂版のKindle版が発売。リフローに対応!

今日気付いたんですが、「詳解 Swift 改訂版」のKindle版がいつの間にか発売されていまし

記事を読む

20150109-223509.jpg

【Xcode 6】対応する開き括弧と閉じ括弧を調べる方法

Xcodeで、対応する開き括弧と閉じ括弧のを調べる簡単な方法があったので紹介したいと思います!

記事を読む

【Mac】macOSのメール(Mail.app)でGmailをサクサク快適に使う方法

macOSに搭載されているメールアプリ、いわゆるMail.ap

【メンズネイル】新宿区大久保のネイルサロンで紫とピンクのネイルにしてもらった

2016年11月12日、東京都新宿区大久保にあるネイルサロン「

[Xcode][Swift]ボタンなどの同時タップを禁止する

iOSで、ボタンなどの同時タップを禁止する方法を紹介します。

【HomeKit】家の照明をSiriで制御できるようにしてみた

Apple製品と家電を連携するシステム「HomeKit(ホーム

【メンズネイル】新宿区大久保のサロンでターコイズとピンクのメタルネイルにしてもらった

2016年10月22日、いつもお世話になっているネイルサロン「

→もっと見る

PAGE TOP ↑