はじめに
今までMain.storyboardに複数ViewControllerを作ってアプリ開発をしていました。しかし、今後storyboardを分割して開発をするにあたって、このstoryboardにあるViewControllerとコードで書いたViewController.swiftの関係ってどうなっているんだろうと思い、調べたことを記事にしました。
以降この記事ではこの二つを区別するため、
ViewController(コード) ※コードで書いたViewController.swift
ViewController(SB) ※Storyboardに作ったViewController
と書きます。
何を書いたか
アプリ起動から画面表示までのViewController(コード) と
ViewController(SB)の変遷を書きます。
なぜ書いたか
本題を調べるにあたって、様々な記事を参考にさせていただいたのですが、私が基本的な部分を理解してなかったため、なかなか記事を読んでも理解が深まりませんでした。私自身の今回調べたことの整理を兼ねて、同じような疑問を持った方の参考になったら嬉しいです。
説明
それではアプリ起動→画面に表示までの流れに沿って説明していきます。
先に説明しておきたいこと
表現が正確かは自信がないですが、私の理解ではViewController(コード) とViewController(SB)の2つは別々にインスタンス化され、ViewController(コード)にViewController(SB)の情報が取り込まれてインスタンス化され画面に表示されているというイメージかと思いました。
この点を押さえた上で読み進めていただけたら幸いです。
準備
今回はXCodeで新規プロジェクトを立ち上げて、初期状態からInterfaceBuilderのViewControllerのルートビューを青にしただけのプロジェクトを例に使って説明していきます。
Main.storyboard読み込み
まずプロジェクトの初期状態だと、Info.plistが下の画像のような設定になっています。
一番下の行に、「Storyboard Name」とあり、これが最初に読み込まれる画面になるのですが、Mainが指定されています。Mainにはview controllerしかなく、Entry Pointに指定されているので、ViewController(SB)が読み込まれます。
最初の画像からもわかるようにViewControlle(SB)のCustom ClassはView Controller(コード)に指定されリンクされているので、次にViewController(コード)が自動でインスタンス化されます。
init?(coder: NSCoder)関数
インスタンス化される際に、コード上では確認できませんが(おそらく内部で自動で呼ばれてる)init?(coder: NSCoder)関数がよばれ、リンクされたView controller(SB)のファイルがデコードされて読み込まれます。この関数によって、ViewController(コード)とViewController(SB)のプロパティが統合され初期化されることになります。今回はしていませんが、この処理によってViewControllerに設定されたアウトレットやアクションなども接続がされます。
ただこの状態のままだとViewControllerのviewプロパティはnilの状態なので、viewが画面に表示される準備はできていません。
viewプロパティ
UIViewControllerにはviewプロパティというものがあります。
ここに格納されたview階層が画面に表示されることになります。
このviewプロパティが要求された時にloadView()という関数が実行されます。
この関数によって関連づけられたViewController(SB)ファイルがロードされViewController(コード)のviewプロパティにview階層が設定され、青い画面が表示されることになります。
ちなみにこのloadView()が行われ、画面に表示される準備ができた後、おなじみのviewDidload()が呼ばれるようになります。
参考書籍・リンク
『親切すぎるiPhoneアプリ開発の本』
Apple 公式ドキュメント UIKit
Apple 公式ドキュメント Foundation
最後に
今まで、storyboard上で対応するViewControllerをCustom Classに設定すればリンクされる程度の理解でした。
調べていくとコード上で確認できない自動で行われている処理が多くあり、それがあって、簡単にViewControllerのリンクができていたことに気づきました。
しかし、storyboardの分割やカスタムセルを使ったり、Interface Builderを使わないで開発をするためにも、今回の内容は重要だと思います。
まだ理解が不十分な部分もあり、誤っている点もあるかと思いますが、理解が深まったら記事を更新していきたいと思います。
最後まで読んでいただきありがとうございます!