【Xcode】Storyboard Referenceを活用してみた

# Storyboard Reference とは
Storyboard Referenceとは、**Stroryboardを分割する**ことができる機能。

例えば、UITabBarControllerを用いて初期画面に５つのタブメニューを設けたい場合、
以下のようにMainStoryboard上に画面遷移で利用するSeguaが複数存在し複雑になってしまう。
<img width="1439" alt="storyboard_reference_before_tabbarcontroller.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/991e52ef-9f92-5d7d-d72e-8e16c137bec7.png">


このような場合に、一つの選択肢として**Storyboard Referenceの活用**が挙げられる。

# Storyboard Referenceのメリット
- Storyboard全体の可視性向上 
5つのタブを把握する度に、いちいち縮小表示しなくて済む.　
また画面数が増えた場合においても、可視性が維持できる.

- 集中力の向上 
５つのタブを1つずつのStoryboardにすることで、1つのタブに集中できる（**1Tab1Storyboard**）

# 目的
今回は、上記Stroryboard上に存在する既存のタブメニュー5つ

- Search
- Bookmarks
- Favorites
- Contacts
- History 

をStoryboard Referenceを活用して、それぞれ1つずつのタブとしてStoryboardに置き換える。

以下、置き換え前後をまとめたリポジトリです。
※２つのサンプルアプリを入れています
BeforeApp　 : Storyboard Reference導入前のサンプルアプリ
AfterApp　　: Storyboard Reference導入後のサンプルアプリ
https://github.com/CHU-BURA/StoryboardReference


# 作業工程
1. Storyboardファイルの新規作成
2. UINavigationControllerとUIViewControllerの設定
3. Storyboard Referenceの配置
4. Segueの設定
5. MainStoryboardと新規Storyboardの紐づけ

# Storyboard Referenceの実装
## 1. Storyboardファイルの新規作成
1. メニューバーから `[File]　>　[New]　>　[File...]`を選択 または `command + N`を実行する。
2. `[Storyboard]` を選択する。
    <img width="729" alt="storyboard_reference_1_create_new_file.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/1c5698d7-9306-7b4b-2139-61dce1fdb5a2.png">
3. ファイル名を入力する。  
新規作成したStoryboardのファイル名については、そのStoryboardがなんの目的・機能をもつのかをもとに決定します。  
※5つのタブの表記名とします。→今回は、`Search.storyboard`

## 2. 新規Storyboardの設定
新規作成したStoryboardをStoryboard Referenceを使用した構成に置き換えます。

### 2-1. StoryboardにUIViewControllerを追加する
右下の[View Controller]をドラッグ&ドロップして、ViewControllerを配置します。
<img width="1435" alt="storyboard_reference_create_view_controller.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/27bba632-47e4-45ce-a822-0e60f9983f34.png">

### 2-2. UINavigationControllerを組み込む
配置したUIViewControllerにUINavigationControllerを組み込みます。  
UIViewControllerを選択し、画面上部のメニューバーより `[Editor] > [Embed in] > [Navigation Controller]` を選択します。
<img width="1440" alt="storyboard_reference_create_navigation_controller.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/3508dc6a-d821-9e4b-7fbf-4a8d68bc479c.png">  
以下のように、UIViewControllerに接続されたUINavigationControllerが作成されます。
<img width="1440" alt="storyboard_reference_created_navigation_controller.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/db33a1e7-a38a-d795-c5e8-2f5986eeaaec.png">


### 2-3. Is Initial View Controller を設定する
接続したUINavigationController選択し（①）、右側のUtilitiesエリアから`[Is Initial View Controller]`にチェックを入れる（②）
チェックを入れると、UINavigationControllerの左側に矢印が表示される(③)
<img width="1440" alt="storyboard_reference_navigation_controller_add_initialview.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/b2d829c4-608c-c8a7-a1fa-83853fd51345.png">
> 「**Is Initial View Controller**」 は 
> アプリを起動した際に、どのUIViewControllerから表示するのかを設定します。これがStoryboard上の開始地点となります。
> ※この設定がしなかった場合は、最初に表示する画面が見つからずクラッシュしてしまいます。

### 2-4. タブの設定
新規のStoryboardに対して、5つのタブの中から対象のタブを設定する。
※今回の対象タブは、`Search`とする。

1. 右下のObjectLibraryエリアから `[Tab Bar Item]` をドラッグ&ドロップしてViewControllerの下側に配置する（①）
2. 右側のUtilitiesエリアから `[System Item] > [Search]` に設定する（②）
<img width="1440" alt="storyboard_reference_add_tabbaritem.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/aef86442-edf7-76d0-e198-30aa1d1cfa8d.png">

### 2-5. タイトル / 背景色 の設定
各5つのタブメニューから遷移した際に区別しやすいように、UIViewControllerにタイトルと背景色を追加する。

1. UIViewControllerの `Navigation Item`　を選択し（①）、右側のUtilitiesエリアの `[Title]`　を入力します（②）
※今回は、`Search`とする。
<img width="1440" alt="storyboard_reference_view_controller_add_title.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/e3fbe728-31af-4453-3866-ed0f256578ac.png">

2. UIViewControllerの `View` を選択し、右側のUtilitiesエリアの `[Background]` を設定する（③）
※今回は、`White Color`とします。
<img width="1440" alt="storyboard_reference_view_controller_add_backgroundcolor.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/5dca9083-6a2a-6c5b-2a65-05a9dcbcac7f.png">


これで1つのタブメニュー側の設定が完了したので、次にMainのStoryboard側を設定します。

## 3. MainStoryboardの設定
MainのStoryboardに戻り、さきほど新規作成したStoryboardをStoryboard Referenceに設定します。

### 3-1. Storyboard Referenceを 配置 / 設定 する
1. 右下のObjectLibraryエリアから `[Storyboard Reference]` をMainStoryboard上にドラッグ&ドロップで配置する。
2. 配置したStoryboard Referenceを選択し、右側のUtilitiesエリアにある `[Storyboard]` に先ほど新規作成したStoryboardのファイル名を指定する。
※今回は、`Search.storyboard`とする。
<img width="1461" alt="storyboard_reference_main_add_storyboard_reference.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/1123156d-6fbf-1fc4-3cc5-05850e41964e.png">

### 3-2. Storyboard Referenceを接続する
設定したStoryboard ReferenceをViewControllerに接続します。
今回は、UITabBarController内の１つのタブメニュー(Search)をViewControllerとして登録します。

UITabBarControllerを選択した状態で、`Controllキー`を押しながら先ほど配置したStoryboard Referenceにドラッグ&ドロップする。
<img width="1440" alt="storyboard_reference_tabbar_add_storyboard_reference.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/264be0e5-e954-a3b7-77eb-857f328c44a1.png">

接続したら、接続先の関係性が聞かれます。
今回はUITabBarControllerのタブの1つとして登録するため、接続先の関係性に **遷移**`[Relationship Segue:view controllers]` を選択します。
<img width="1440" alt="storyboard_reference_tabbar_add_relationship.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/a1f8c6e0-5f9a-31a8-54e9-b3c30fa53d21.png">

以下のように、Segueで接続されて表示されていれば問題ありません。<img width="1440" alt="storyboard_reference_tabbar_segue.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/5787307d-b9db-1a27-1c07-745e55fc5bb0.png">

### 3-3. タブの設定 ※追記の反映内容
MainのStoryboardのUITabBarControllerに該当するタブアイコンを設定します。
UITabBarControllerの各`Tab Bar Item`を選択し、右側のUtilitiesエリアにある `[System　Item]` にそれぞれ該当するタブを指定する。
※今回は`Search`を指定する。
<img width="1440" alt="storyboard_reference_complete_fixed_clear.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/7a3ca8d9-3814-5c5d-3aa4-debc54908ac3.png">

### 3-4. 既存タブ接続の解除　※既存タブメニューありの場合
接続が完了したら、もともとUITabBarController側で設定していた対象タブに接続されているUINavigationControllerとUIViewControllerを削除する。
※新規でUITabBarControllerを作成した場合は、スキップしてください。
<img width="1440" alt="storyboard_reference_old_segue.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/d78f0324-87bc-2747-504d-80955a2a322e.png">


## 4. 残りのタブ作成
ここまでで、1つのタブメニュー`Search`をStoryboard Referenceへ置き換える作業が完了しました。
残り4つのタブメニュー `Bookmarks`、`Favorites`、`Contacts`、`History` も、1~3の工程同様に繰り返します。

UITabBarControllerの全タブをStoryboard Referenceに置き換えたら設定完了です。
MainStoryboard上がとてもシンプルになり、スッキリしました。
<img width="1440" alt="storyboard_reference_re_complete.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/34a1720e-a9a4-114b-20cd-38a8d51c070b.png">


# 追記
## MainStoryboard上におけるアイコンの表示がされない
全タブのStoryboard Reference置き換え完了後、特に動作上は問題ありませんが、
以下のようにMainのStoryboard上での各タブアイコンの表示が反映されていないことに気づきました。~~※後ほど調査し反映しようと思います。~~
<img width="1440" alt="storyboard_reference_complete_fixed.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/a03f9206-eebb-6047-5e01-b76cbf810e00.png">
【原因】
Storyboard上の可視性を向上させるという意味で改善する必要があると思い調査したところ、
MainのStoryboard側のUITabBarControllerにおいて、各`Tab Bar Item`に対象のタブを設定していないためアイコンが表示されていませんでした。
【対処方法】
UITabBarControllerの各`Tab Bar Item`を選択し、右側のUtilitiesエリアにある `[System　Item]` をそれぞれ該当するタブに設定する。
※上記説明箇所には反映済みです。
<img width="1440" alt="storyboard_reference_complete_fixed_clear.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/aeb5998c-7440-b3b6-9c75-2d38dd5a0a00.png">