頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


storyboardファイルを軽くするためxibを切り離す時のAutolayoutについて

本記事はXcodeのstoryboadファイルをサクサクと開けるハイスペックなMacをお持ちの方には関係のない話です。😄

ウチの非力なMac minだとstoryboadファイルを表示させるのに少々時間がかかる。
プロジェクト作成時にできるMain.storyboardにどんどんと書き込んで行くと次第に表示までの時間も長くなってくる、、、(測ってないけど多分そうだろう)。

重いstoryboardファイル

↑クリックするのが億劫になってくる(でもしないわけにもいかん!)
storyboardファイルはGUIで扱うので仕方ないんだけどなんとかならないものか?

というこで分離できないか検討した。


今考えているのはタブバーを使うアプリなので、Main.storyboardではタブ周りの設定だけにする。
まず、Xcodeでタブバーアプリを選択し新規プロジェクトを作成する。するとタブを二つ持つプロジェクトができる。

重いstoryboardファイル

↑これはそれにFirstViewControllerにだけナビゲーションバーをかませたもの。

このFirstViewControllerをただのコンテナとし、そこに乗せるのをChildFirstViewControllerとする。

Xcodeのファイル作成画面

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

Xcodeで作成されたファイル

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

ところが問題はAutolayoutだ。

ChildFirstViewController.xibのsafe areaが使えるのか?

constraintを設定したview

↑確認のため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)

↑すると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)を追加するといけた。

成功時の実行結果(iPhone 5s)

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

成功時の実行結果(iPhone XS Max)

↑XS Maxでの実行結果。こっちもおっけー!

なお、上記constraintの設定後に、ChildFirstViewControllerの viewDidLoad: がコールされる。したがってここで初期設定を行えばよい。
これなら viewDidLayoutSubviews を使わないで実現できる(このメソッドはなるべく使いたくないのである)。

ということでこれでやってみる。不具合あったら追記する。



追記!↑これじゃダメだった!!!ので続きはこちら↓

スポンサーサイト




<< タブごとにstoryboardファイルを分ける  TopPage  アプリの画面を録画する(2)AVAssetWriterではまった話 >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
https://ringsbell.blog.fc2.com/tb.php/1309-acece276




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.