しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

AutoLayoutで発生する謎の16pxのマージンについて調べてみた (constrain to margin)

Autolayoutを使い始めて最初につまずいたのが、謎の16pxのマージンでした。
今回はそのマージン周りについて調査してみました。
下画像のように、Storyboardで親ビューと同じサイズになるようにMargin0のconstrainを作成します。

constrain to margin

f:id:llcc:20150524190319p:plain

上設定で緑のビューが全画面になると思いきや下のように左右にMarginが発生します。

f:id:llcc:20150524190425p:plain

これはconstrain作成時のconstrain to marginというチェックボックスをOnにしていると起こる現象です。
それさえ取り去れば無事に全画面になってくれます。

f:id:llcc:20150524185749p:plain

constrain to marginにチェックを入れて作成した物のMarginを取りたい場合は、constrainを選択して設定からRelative to marginのチェックを外せば変更する事ができます。

f:id:llcc:20150524190642p:plain

layoutMargins

この16pxがどこから来ているかと言うと、親ViewのlayoutMarginsプロパティーの値から来ています。
親ViewのlayoutMarginsが{0, 16, 0, 16}になっているので左右に16pxの隙間が空きます。
実際に親ViewのlayoutMarginsのを{0, 0, 0, 0}にすると隙間はなくなります。

override func viewDidLayoutSubviews() {
    self.view!.layoutMargins = UIEdgeInsetsZero
}

あと不思議な事に、windowのrootViewControllerのビュー以外ではlayoutMarginsの値は{8, 8, 8, 8}になります。
確認した所、viewWillAppearviewWillLayoutSubviewsの間のタイミングで{0, 16, 0, 16}に変換されていました。

上記に関連して一点注意があります。
rootViewControllerのビューにUIEdgeInsetsZeroセットするのはviewWillLayoutSubviewsviewDidLayoutSubviewsで行う必要があります。
理由としては、viewWillAppearの後に{0, 16, 0, 16}への変換が走ってしまうためです。

layoutMarginsのまとめ

layoutMarginsについて色々と調べましたが、何も考えずにconstrain to marginのチェックを外すのが一番楽そうだと感じました。
しかしlayoutMarginsを使う事でマージンの値を一箇所で管理できるというメリットもあるので、場合によっては使ってみても良いかと思います。