iOSでは、通常画面のパーツをカスタムViewとして作成して使用することはよくある。
だが、そのパーツの中で画面遷移をしたいと思う場合もあるだろう。
例えば、TabBarControllerのようにだ。

そういう場合は、自分独自のContainerViewControllerを作成すれば良い。
作り方はシンプルなので、恐れることはない。

それでは作成を開始しよう。
 
カスタムContainerViewControllerを作る
まずはガワとなるViewControllerを作成しよう。
ソースファイルは出来合いのViewController.swiftを使用する。

まずはStoryboardで以下のように画面を設定しよう。
custom_container_view_controller01
オレンジの部分が子供となるViewControllerのViewを表示するためのUIView(以後、表示Viewと呼ぶ)で、下にある2つのボタンで、ViewControllerを切り替えるという仕様にする。

表示Viewと2つのボタンはソースに接続しておこう。
現在のソースはこのようになる。

changeVC1, changeVC2の二つのメソッドはボタンを押した時のActionだ。

子ViewControllerを作る
子供となるViewControllerを作成しよう。
Storyboardで以下のように2つのViewControllerを作成する。
custom_container_view_controller02
中央にLabelを配置しただけのシンプルなものだ。

次に、これらのViewControllerのIdentity InspectorでStoryboard IDをそれぞれvc1, vc2と設定しておく。
custom_container_view_controller03
これで、ソースからこれらの子ViewControllerを呼び出せるようになった。

それでは、ソース側で子Viewの作成と追加を行ってみよう。

まずはこのように2つの子Viewを保持するためのクラス変数を用意する。
childVCは現在子として表示しているViewControllerを保持するためのものだ。

次に以下のコードをviewDidLoad()の最後に追加しよう。

1.2つの子ViewControllerインスタンスを作成する。
 また、サイズは表示Viewに合わせておく

2.子1をContainerViewControllerの子として追加する

3.表示ViewのサブViewとして、子1のviewを追加する。

4.子1に対して処理の終了を通知する。

5.現在表示している子を保持する。
 初期はもちろん子1だ。

それでは実行してみよう。
custom_container_view_controller04
想定通りのレイアウトで表示された。
次は子の切り替え処理を実装しよう。

ボタンのイベントハンドラを以下のようにする。

1.現在の子を一旦削除する処理だ。
 これは絶対に忘れないようにしよう。

2.子を追加する。
 内容は上記で説明したものと同じだ。

それでは実行してみよう。
ボタンによる子の切り替えができるようになっているはずだ!

さて、実行してみておかしなことに気づいたはずだ。
子2に切り替えた時にレイアウトがおかしくなっている。
custom_container_view_controller05
これはなぜだ。
実は先程のコードには誤りがある。
子の持つviewのframeの設定が正しくないのだ。
正しく表示されるように修正しよう。

まず、viewDidLoad()内のframeの設定を削除しよう。
次にviewDidLayoutSubviews()を以下のように実装する。

これで実行してみよう。
custom_container_view_controller06
正しく表示された!
これで完了だ。

子にNavigationControllerを設定する
子にはNavigationControllerを設定することも出来る。
Storyboardで以下のようにNavigationControllerを作成しよう。
custom_container_view_controller07
次にNavigationControllerにStoryboard IDをnavと設定しておく。
custom_container_view_controller08
これで準備は完了だ。
ソースの変更に取り掛かろう。
以下はほぼ全文になるが、その方がわかりやすいと思うので載せる。

1.vc1を削除し、代わりにNavigationControllerのインスタンスであるnavを宣言する。

2.navを作成する。

基本的にはこれだけだ。
上記の2箇所を修正すると、vc1が無い旨のエラーがたくさん出るので、vc1をnavに書き換える。

それでは実行してみよう。
custom_container_view_controller09
想定通り、表示Viewの中で画面遷移を行うことが出来た!

参考文献
カスタムContainer View Controllerを作る - Qiita