storyboardファイルを軽くするためxibを切り離す時のAutolayoutについて
本記事はXcodeのstoryboadファイルをサクサクと開けるハイスペックなMacをお持ちの方には関係のない話です。😄
ウチの非力なMac minだとstoryboadファイルを表示させるのに少々時間がかかる。
プロジェクト作成時にできるMain.storyboardにどんどんと書き込んで行くと次第に表示までの時間も長くなってくる、、、(測ってないけど多分そうだろう)。

↑クリックするのが億劫になってくる(でもしないわけにもいかん!)
storyboardファイルはGUIで扱うので仕方ないんだけどなんとかならないものか?
というこで分離できないか検討した。
今考えているのはタブバーを使うアプリなので、Main.storyboardではタブ周りの設定だけにする。
まず、Xcodeでタブバーアプリを選択し新規プロジェクトを作成する。するとタブを二つ持つプロジェクトができる。

↑これはそれにFirstViewControllerにだけナビゲーションバーをかませたもの。
このFirstViewControllerをただのコンテナとし、そこに乗せるのをChildFirstViewControllerとする。

↑Xcodeでファイル作成時にxibも一緒に作成する(Also create XIB file)にチェックする。

↑するとこのように.hと.mファイルと共にxibファイルができる。
ここからの展開はこちらのxibファイルに書き込む。つまりタブごとにファイルが分かれるので、管理しやすくなるのでは!?と考えてる。
ところが問題はAutolayoutだ。
ChildFirstViewController.xibのsafe areaが使えるのか?

↑確認のためChildFirstViewController.xibで上のように、safe areaの左上と右下に四角形、上部中央に文字列を表示するようなconstraintの設定をした(View as: iPhone XRで設定)。
そして以下のような単純な方法でコンテナ (FirstViewController)に乗せる。

↑するとiPhone 5sではこのようにsafe areaが意図通りには伝わっていないことがわかる。
子側のviewサイズが親側のと同じにする簡単な方法はないものか、と調べると、、、
objective c - Autolayout constraints and child view controller - Stack Overflow
↑こういう記事を発見。やりたいこと同じやん!。
この記事の回答を参考にして以下のようにしてみた。
まず乗せる方。
↑作成したオブジェクトにselfを渡すのってどうよ、、、と思わないでもないがここは仕方ない。
次に乗る側。
↑まあstackoverflowのままなんだけど、そのままだとXS Maxだといけるのに5sだとワーニングが吐かれて正常に表示されなかった。(1)を追加するといけた。

↑5sでの実行結果。よしよし!

↑XS Maxでの実行結果。こっちもおっけー!
なお、上記constraintの設定後に、ChildFirstViewControllerの viewDidLoad: がコールされる。したがってここで初期設定を行えばよい。
これなら viewDidLayoutSubviews を使わないで実現できる(このメソッドはなるべく使いたくないのである)。
ということでこれでやってみる。不具合あったら追記する。
追記!↑これじゃダメだった!!!ので続きはこちら↓
ウチの非力なMac minだとstoryboadファイルを表示させるのに少々時間がかかる。
プロジェクト作成時にできるMain.storyboardにどんどんと書き込んで行くと次第に表示までの時間も長くなってくる、、、(測ってないけど多分そうだろう)。

↑クリックするのが億劫になってくる(でもしないわけにもいかん!)
storyboardファイルはGUIで扱うので仕方ないんだけどなんとかならないものか?
というこで分離できないか検討した。
今考えているのはタブバーを使うアプリなので、Main.storyboardではタブ周りの設定だけにする。
まず、Xcodeでタブバーアプリを選択し新規プロジェクトを作成する。するとタブを二つ持つプロジェクトができる。

↑これはそれにFirstViewControllerにだけナビゲーションバーをかませたもの。
このFirstViewControllerをただのコンテナとし、そこに乗せるのをChildFirstViewControllerとする。

↑Xcodeでファイル作成時にxibも一緒に作成する(Also create XIB file)にチェックする。

↑するとこのように.hと.mファイルと共にxibファイルができる。
ここからの展開はこちらのxibファイルに書き込む。つまりタブごとにファイルが分かれるので、管理しやすくなるのでは!?と考えてる。
ところが問題はAutolayoutだ。
ChildFirstViewController.xibのsafe areaが使えるのか?

↑確認のためChildFirstViewController.xibで上のように、safe areaの左上と右下に四角形、上部中央に文字列を表示するようなconstraintの設定をした(View as: iPhone XRで設定)。
そして以下のような単純な方法でコンテナ (FirstViewController)に乗せる。
// FirstViewController class
- (void)viewDidLoad
{
[super viewDidLoad];
ChildFirstViewController *childFirstVC = [[ChildFirstViewController alloc]
initWithNibName:@“ChildFirstViewController" bundle:nil];
[self addChildViewController:childFirstVC];
[self.view addSubview:childFirstVC.view];
}

↑するとiPhone 5sではこのようにsafe areaが意図通りには伝わっていないことがわかる。
子側のviewサイズが親側のと同じにする簡単な方法はないものか、と調べると、、、
objective c - Autolayout constraints and child view controller - Stack Overflow
↑こういう記事を発見。やりたいこと同じやん!。
この記事の回答を参考にして以下のようにしてみた。
まず乗せる方。
// FirstViewController class
- (void)viewDidLoad
{
[super viewDidLoad];
ChildFirstViewController *childFirstVC = [[ChildFirstViewController alloc]
initWithNibName:@“ChildFirstViewController" bundle:nil];
[childFirstVC setupWithParentController:self];
}
↑作成したオブジェクトにselfを渡すのってどうよ、、、と思わないでもないがここは仕方ない。
次に乗る側。
// ChildFirstViewController class
-(void)setupWithParentController:(UIViewController *)parent
{
UIView *view = [self view];
[self willMoveToParentViewController:parent];
[parent addChildViewController:self];
view.translatesAutoresizingMaskIntoConstraints = NO;//—(1)
[parent.view addSubview:view];
[self didMoveToParentViewController:parent];
NSArray *horizontalConstraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-0-[view]-0-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(view)];
[parent.view addConstraints:horizontalConstraints];
NSArray *verticalConstraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-0-[view]-0-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(view)];
[parent.view addConstraints:verticalConstraints];
}
↑まあstackoverflowのままなんだけど、そのままだとXS Maxだといけるのに5sだとワーニングが吐かれて正常に表示されなかった。(1)を追加するといけた。

↑5sでの実行結果。よしよし!

↑XS Maxでの実行結果。こっちもおっけー!
なお、上記constraintの設定後に、ChildFirstViewControllerの viewDidLoad: がコールされる。したがってここで初期設定を行えばよい。
これなら viewDidLayoutSubviews を使わないで実現できる(このメソッドはなるべく使いたくないのである)。
ということでこれでやってみる。不具合あったら追記する。
追記!↑これじゃダメだった!!!ので続きはこちら↓
スポンサーサイト
<< タブごとにstoryboardファイルを分ける TopPage アプリの画面を録画する(2)AVAssetWriterではまった話 >>
トラックバック
トラックバックURL
https://ringsbell.blog.fc2.com/tb.php/1309-acece276
https://ringsbell.blog.fc2.com/tb.php/1309-acece276