ストーリーボードのいいところとこまったところ
iOSアプリ開発では、ストーリーボードをつかって画面をレイアウトします。
ストーリーボードは名前のとおり、アプリのストーリー(画面遷移)も管理できてとても便利です。
しかし、いくつか不便な点もあります。
そのひとつが、コンフリクト(競合)です。
ストーリーボードの実態はひとつのおおきなXMLファイルなので、複数人で編集するとあっというまにコンフリクトをおこします。
また、Gitで複数のブランチを作成し、それぞれのブランチでストーリーボードを編集してからマージすると、またまたコンフリクトです。
しかも、このコンフリクトはとてもなおしにくいです。
もし発生したら、片方のブランチの編集内容を放棄して、もういちどストーリーボードを編集するくらいのガッツが必要です。
ストーリーボードを分割しよう
そんな悩みを解決してくれるのが、ストーリーボードの分割です。
Xcodeでは、ストーリーボードを複数作成できるので、コンフリクトをおこさないような単位でストーリーボードを分けてしまいます。そうすれば、コンフリクトの悩みから解放されます。
今回の例では、Main
と Sub
のふたつのストーリーボードを作成しています。
それでは、 Main
から Sub
の画面(ViewController)を呼び出してみましょう。
まず、呼び出されるストーリーボード( Sub
)の設定をします。
最初に表示するViewControllerを is Initial View Controller
に設定します(画面右ユーティリティーエリアの is Initial View Controller
にチェックを入れると、ViewControllerの横に矢印がつきます)。
つぎに、先ほど Initial
に設定したViewController( SubViewController
)に、自分自身のインスタンス化処理を書きます。
static func instantiateSubViewController() -> UIViewController? {
let storyboard = UIStoryboard(name: "Sub", bundle: nil)
let initialViewController = storyboard.instantiateInitialViewController()
return initialViewController
}
name: "Sub"
には、ストーリーボードの名前を書きます。
(この処理を呼び出される側に書いたのは、ストーリーボード名を隠蔽するためです)
あとは、呼び出す側(今回の例では Main
ストーリーボードの画面)で、次のプログラムを実行すると、 Sub
ストーリーボードの Initial
に設定したViewController( SubViewController
)が表示されます。
if let subViewController = SubViewController.instantiateSubViewController() {
present(subViewController, animated: true, completion: nil)
}
画面遷移するときにデータを渡したい場合は、 present
の前でプロパティをセットするなり、値をセットするメソッドを呼び出すなりします(prepare
メソッドが必要ないので、こちらの方が見通しはいいですね。)。
戻るときは通常の画面遷移とおなじで、 dismiss
をつかいます。
dismiss(animated: true, completion: nil)
コンフリクトにお悩みのあなたは、意外に簡単便利なストーリーボードの分割をおためしください。
参考
iOS9以降ではノンコーディングでストーリーボードを分割できます。詳しくは、[iOS 9] ノンコーディングで Storyboard を分割できる Storyboard Reference をご覧ください。