「Refactor to Storyboard」で一定のフローをひとつのStoryboardとしてまとめておくと便利

Xcode7から使えるようになったStoryboard Referenceを使うとコードを書かずにStoryboard間の参照ができるようになりました。 

既にStoryboard内にあるViewControllerからStoryboard Referenceを作る時の流れは、
1. 別のStoryboardに分けたいViewControllerを選択(複数選択可)
2. Editor > Refactor to Storyboard... を選択
3. ダイアログに従ってStoryboardファイル作成

です。
>参考
[Refactoring Storyboards](https://developer.apple.com/library/ios/recipes/xcode_help-IB_storyboard/Chapters/RefactorStoryboard.html#//apple_ref/doc/uid/TP40014225-CH48-SW1) 

## Storyboard Referenceを使ってStoryboardをキレイに
今までゴチャゴチャしていたStoryboardファイルが
![qiita20151219_01.png](https://qiita-image-store.s3.amazonaws.com/0/40702/05c164d5-8715-a782-b2c3-e7b26949f6f0.png "qiita20151219_01.png")

Storyboard Referenceを使うことでSegueの接続でStoryboard同士を連携することができるようになり、簡単にキレイに保つことができるようになりました。
![qiita20151219_02.png](https://qiita-image-store.s3.amazonaws.com/0/40702/5a503a0b-51db-2f80-e108-cca2478dd105.png "qiita20151219_02.png")

Storyboardに切り出す時に使う`Refactor to Storyboard...`を使えば **ひとつのフローをそのままひとつのStoryboardとして切り出す** というようなこともできます。
## Storyboard Referenceを使った時のビルドエラー
便利だなーと思って`Refactor to Storyboard...`でStoryboard Referenceを作っていると、ビルドエラーになることがありました。  
Storyboard Referenceは基本的には`Deployment Target iOS 8.0`から使えるのですが、`iOS 9.0`以前のバージョンだとビルドエラーになる場合があります。
![qiita20151219_04.png](https://qiita-image-store.s3.amazonaws.com/0/40702/2a634a46-19f9-3624-2396-80441653136e.png "qiita20151219_04.png")

## 「Storyboard References cannot be the destinations of relationship segues prior to iOS 9.0」とビルドエラーが出た時の対処法
「relationship segueで繋ぐ先にStoryboard Referenceを指定するにはiOS 9.0以上じゃないとダメだよ」っていうようなエラーなのですが、具体的にはTabBarControllerやNavigationControllerから直接Storyboard Referenceを繋げると起こります。

せっかく別のStoryboardに分けたフローはそのまま残しておきたいので、Storyboard Referenceを使わずにコードでStoryboardを呼び出すように変更します。
### TabBarControllerの場合
Storyboard上で繋がっていたStoryboard Referenceを削除し、UITabBarControllerだけにします。
`Refactor to Storyboard`で作ったStoryboardファイル自体は残しておきます。
![qiita20151219_03.png](https://qiita-image-store.s3.amazonaws.com/0/40702/35576e69-e69e-7c8e-f1c0-a6dedbc25098.png "qiita20151219_03.png")

コードではUITabBarControllerを継承したクラスを作り、UITabBarControllerのviewControllersを指定します。  

```
class TabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let firstViewStoryboard = UIStoryboard(name: "FirstView", bundle: NSBundle.mainBundle())
        let secondViewStoryboard = UIStoryboard(name: "SecondView", bundle: NSBundle.mainBundle())
        
        let firstViewController = firstViewStoryboard.instantiateInitialViewController()
        let secondViewController = secondViewStoryboard.instantiateInitialViewController()
        
        self.viewControllers = [firstViewController!, secondViewController!]

        // Do any additional setup after loading the view.
    }
    
}
```
UITabBarControllerではStoryboard Referenceを使わなくなるので、先ほどのビルドエラーは解消され、`Refactor to Storyboard...`で作ったStoryboardファイルはそのまま使うことができます。
### NavigationControllerの場合

NavigationControllerでも同じようにコードで、UINavigationControllerのviewControllersを指定します。

```
class NavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let navigationStoryBoard = UIStoryboard(name: "Navigation", bundle: NSBundle.mainBundle())
        let navigationViewController = navigationStoryBoard.instantiateInitialViewController()
        
        self.viewControllers = [navigationViewController!]
    }

}
```

## さいごに
「設定画面のStoryboard」や「チュートリアル画面のStoryboard」のように、 **一定のフローをひとつのStoryboardとしてまとめておく** とフロー自体をそのまま別アプリでも再利用できるので便利です。

個人で作った[みんなのリスト](https://itunes.apple.com/jp/app/minnanorisuto/id1065194661)というアプリの開発時には、メインアプリとは別にチュートリアルだけの小さなプロジェクトファイルを作って、ある程度できた段階でStoryboardごとメインアプリの方に移したりしていました。