

こんにちは。  
調べてもどうしても出てこなくて困っています。  
xibのView作成についてなど2つ質問させていただきたいです。  
(実行環境 Xcode 8.2.1 / Swift 3.0.2)

* * *

# 1つ目

[code]

    class CustomView: UIView {
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            let view = Bundle.main.loadNibNamed("Custom", owner: self, options: nil)?.first as! UIView
            view.frame = bounds
            addSubview(view)
        }
    }
    
[/code]

このようにxibファイルのViewをロードして、viewの子としてaddし、サイズを調節することで  
CustomViewとしていることを記事などで調べていました。また、ここで

[code]

    translatesAutoresizingMaskIntoConstraints = false
    
[/code]

と、システムが管理するAutoResizeMaskの自動制約追加を無効にして  
AutoLayoutを設定している記事もありました。  
どちらにしても、実行時にはサイズが調節され、同じサイズになっています。

[code]

    view.frame = bounds
    
[/code]

とする方では、initの時点ではViewのサイズなどのレイアウトは決まっていないはずなのです。  
私はiPhone5のサイズ(320 × 568)のViewControllerをStoryboardで用意し、

[![directory](https://i.stack.imgur.com/Q1POA.png)](https://i.stack.imgur.com/Q1POA.png)  
CustomViewにはViewControllerの持つViewに対して上下左右 0 と制約をつけて  
iPhone6+(414 × 736)で実行しました。  
もちろん、実行結果はCustomViewが画面いっぱいに表示されるのですが、

[code]

    view.frame = bounds
    
[/code]

このようにレイアウトが確定される前にこの処理をしても  
(管理されるViewControllerのサイズなどが確定するviewDidLayoutSubViewsよりも前に  
このinitは呼ばれる)  
サイズがピッタリに合うのが何故か分かりません。

[code]

    print(view.frame.size)
    
[/code]

などとサイズを確認しても、ここでは320 × 568と表示されます。  
(実際の実行時のサイズは414 × 736です。)

# 2つ目

[ある記事](http://akisute.com/2016/06/auto-layout-manual-
layout.html)でIB上でAutoLayoutを設定したViewには、自動的に

[code]

    translatesAutoresizingMaskIntoConstraints = false
    
[/code]

が設定されて、

[code]

    view.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
    
[/code]

のように、直接変更はできないようになるとあり、確かに自分自身もそのような経験があったような気がしています。しかし、現在ではtranslatesAutoresizingMaskIntoConstraintsに関係なく直接frameなどで位置やサイズの調節ができるのですが、iOS10やXcode8.0などで変更されたのでしょうか？

* * *

* * *

* * *

少しUIViewのリファレンスを見直して見ました。気になった関数やプロパティは以下で

  * autoresizesSubviews 自動リサイズを利用するか(教えて頂いたもの)
  * requiresConstraintBasedLayout 正確に制約が機能する必要があるか(get only)
  * layoutSubViews 制約や自動リサイズよりもサブViewのレイアウトを正確に行う必要がある場合に設定

もし、frameなどの直接指定を行いたい場合は、カスタムクラス内でlayoutSubViews()を  
overrideするのが良いのかなというのが現状の理解です...[iOSレイアウトについてのまとめ](https://developers.eure.jp/tech/ios_layout_beginners/)

[code]

    class CustomView: UIView {
    
        var subView: UIView!
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            subView = Bundle.main.loadNibNamed("Custom", owner: self, options: nil)?.first as! UIView
            //自動リサイズを無効にして、
            autoresizesSubviews = false
            //以下を実行するとViewのサイズはIBの 320 × 568 (6+実行時でも320 × 568 とぴったり合わない)
            //subView.frame = bounds
            addSubview(subView)
        }
    
        //自動リサイズを無効にしても、IB上でAutoLayoutをCustomViewに設定しているのでレイアウト確定時に呼ばれてサイズがぴったり合う
        //(ViewControllerの持つViewに対してautoresizesSubviews = false を設定してもぴったり合ったので、
        //これはAutoLayoutによってレイアウトが確定されることが分かりました。)
        override func layoutSubviews() {
            subView.frame = bounds
        }
    }
    
[/code]


CC BY-SA 3.0
2017-01-09T15:05:03.193
31732
2017-05-17T01:57:39.237
2017-01-10T16:58:58.923
19269
19269
question
swift ios storyboard autolayout xib
xibで作成したViewのサイズを合わせる処理について


この辺り、自分でも曖昧なままで今までやってきていたのですが、ご質問を拝見したのをきっかけにあれこれ調べなおしてみました。

[iOS View
プログラミングガイド](https://developer.apple.com/jp/documentation/ViewPG_iPhoneOS.pdf)  
[View Programming Guide for
iOS](https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/Introduction/Introduction.html)

[UIView](https://developer.apple.com/reference/uikit/uiview)

`UIView`のクラスリファレンスでさえかなりの量のあるドキュメントですんで、結論的な部分だけ書かせていただくと、「サイズがピッタリに合う」動作は

  * 親View側の[`autoresizesSubviews`](https://developer.apple.com/reference/uikit/uiview/1622425-autoresizessubviews)プロパティ
  * 子View側の[`autoresizingMask`](https://developer.apple.com/reference/uikit/uiview/1622559-autoresizingmask)プロパティ

…の値で決まると言うことです。

それぞれ、storyboard/xibのInspectorでは、

`autoresizesSubviews`:  
[![autoresizesSubviews](https://i.stack.imgur.com/BPNoS.jpg)](https://i.stack.imgur.com/BPNoS.jpg)

`autoresizingMask`:  
[![autoresizingMask](https://i.stack.imgur.com/tEivD.jpg)](https://i.stack.imgur.com/tEivD.jpg)

に対応しています。

* * *

と言うわけで、 **1つ目**
についてですが、上記各プロパティの設定が`true`/上下左右のマージンが固定(どちらもstoryboard/xibエディターでの初期状態)になっているためでしょう。

以下に述べますが、`translatesAutoresizingMaskIntoConstraints`を`false`にしても、(制約は使用しない形で)Autoresizingの動作は行われる、と言うことです。

* * *

**2つ目**
についてですが、[`translatesAutoresizingMaskIntoConstraints`](https://developer.apple.com/reference/appkit/nsview/1526961-translatesautoresizingmaskintoco)の値というのは上記のAutoresizingの動作を

  * 制約(constraints)に変換して他の制約と一緒に制約によるサイズ解決の一環として行う
  * 旧来のAutoresizingの動作(制約とは別物)として行う

かを選択するものなので、微妙な動作はiOS(およびSDK)のバージョンによって変化があったかもしれません(制約解決のアルゴリズムは間違いなく変化があって、同じ制約の付け方でもバージョンによってはレイアウトが崩れるなんて経験はおありかと思います)が、コードで直接`frame`等を操作するなら`translatesAutoresizingMaskIntoConstraints`の値だけでなく、上記のAutoresizingの設定も見直さないとダメなはず、と言うことになります。

(申し訳ありませんが、力尽きまして、`frame`の直接指定・旧来のAutoresizing・制約の解決がどのような優先順位・実行順序で行われるのかまでの記述は探せていません。)

と言うわけで2つ目のご質問に関してはきちんとした回答になっていないような気がしますが、とりあえずのご報告ということで。


CC BY-SA 3.0
2017-01-09T16:55:30.810
31735
2017-01-09T16:55:30.810
13972
31732
answer