Git
Xcode
Swift
swift4

【Xcode】意外に簡単なストーリーボードの分割でGitのコンフリクトとさようなら

ストーリーボードのいいところとこまったところ

iOSアプリ開発では、ストーリーボードをつかって画面をレイアウトします。
ストーリーボードは名前のとおり、アプリのストーリー(画面遷移)も管理できてとても便利です。

しかし、いくつか不便な点もあります。
そのひとつが、コンフリクト(競合)です。

ストーリーボードの実態はひとつのおおきなXMLファイルなので、複数人で編集するとあっというまにコンフリクトをおこします。
また、Gitで複数のブランチを作成し、それぞれのブランチでストーリーボードを編集してからマージすると、またまたコンフリクトです。

しかも、このコンフリクトはとてもなおしにくいです。
もし発生したら、片方のブランチの編集内容を放棄して、もういちどストーリーボードを編集するくらいのガッツが必要です。

ストーリーボードを分割しよう

そんな悩みを解決してくれるのが、ストーリーボードの分割です。

Xcodeでは、ストーリーボードを複数作成できるので、コンフリクトをおこさないような単位でストーリーボードを分けてしまいます。そうすれば、コンフリクトの悩みから解放されます。

今回の例では、MainSub のふたつのストーリーボードを作成しています。

storyboard01.png

それでは、 Main から Sub の画面(ViewController)を呼び出してみましょう。

まず、呼び出されるストーリーボード( Sub )の設定をします。

storyboard02.png

最初に表示する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 をご覧ください。