天天看點

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

通過前面幾節,我們已經了解了什麼是限制,以及限制是如何工作的。這一節開始,我們使用自動布局來做一個相冊應用程式。這個程式在水準和垂直模式都可以顯示4副圖檔,效果如下:

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

螢幕被分為4個區域,每個區域由一個Image view和一個Label組成。

建立一個名為Gallery的single view應用程式。打開Main.storyboard,disable Size Classes。添加一個view到畫布上并修改其大小為160x284,将其背景色改為綠色:

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

選中綠色的view,點選打開pin菜單,激活Spacing to nearest neighbor區域的4條紅色T型并點選Add 4 Constraints來建立4個限制:

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

限制建立後效果如下:

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

由于UIView不像UIButton或UILabel,它沒有intrinsic content大小,我們需要足夠的限制來确定UIView的大小。這裡,UIView的大小就是其父view的大小。在Document Outline界面中可以看到,生成的4個限制分别為2個水準間距限制和2個垂直間距限制,它們的值都是固定的。

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

綠色view的寬度就是"其父view的寬度減去(0 + 128 + 2*16)",這裡16為布局的邊界。

綠色view的高度就是“其父view的高度減去(0 + 264)"。

預覽一下,垂直模式下,螢幕分辨率為320x568,綠色view的大小為:160x304

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

水準模式下,螢幕分辨率為568x320,綠色view的大小為:408x56:

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

這裡,我們并不期望綠色view在螢幕旋轉時發生大小的變化,我們通過pin菜單設定長和寬的限制:

iOS 自動布局 Auto Layout 入門 05 相冊 (上)
iOS 自動布局 Auto Layout 入門 05 相冊 (上)

通過預覽檢視效果,垂直方向看起不錯,但是當我們将預覽圖切換到水準模式時,啊哦,綠色view并不是我們所期望的大小,在調試視窗,有如下log輸出:

2015-03-11 21:51:55.481 Gallery[3955:39020] Unable to simultaneously satisfy constraints.
	Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7b35c170 V:[UIView:0x7b35c650(284)]>",
    "<NSLayoutConstraint:0x7b35d300 V:[_UILayoutGuide:0x7b35c9d0]-(0)-[UIView:0x7b35c650]>",
    "<NSLayoutConstraint:0x7b35d390 V:[UIView:0x7b35c650]-(264)-[_UILayoutGuide:0x7b35cee0]>",
    "<_UILayoutSupportConstraint:0x7b35d3c0 V:[_UILayoutGuide:0x7b35c9d0(20)]>",
    "<_UILayoutSupportConstraint:0x7b35c050 V:|-(0)-[_UILayoutGuide:0x7b35c9d0]   (Names: '|':UIView:0x7b35c5e0 )>",
    "<_UILayoutSupportConstraint:0x7b35d270 V:[_UILayoutGuide:0x7b35cee0(0)]>",
    "<_UILayoutSupportConstraint:0x7b35d1c0 _UILayoutGuide:0x7b35cee0.bottom == UIView:0x7b35c5e0.bottom>",
    "<NSLayoutConstraint:0x7b360f30 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7b35c5e0(480)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7b35c170 V:[UIView:0x7b35c650(284)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-03-11 21:51:58.523 Gallery[3955:39020] Unable to simultaneously satisfy constraints.
	Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7b35bfe0 H:[UIView:0x7b35c650(160)]>",
    "<NSLayoutConstraint:0x7b35d330 UIView:0x7b35c5e0.trailingMargin == UIView:0x7b35c650.trailing + 128>",
    "<NSLayoutConstraint:0x7b35d360 UIView:0x7b35c650.leading == UIView:0x7b35c5e0.leadingMargin>",
    "<NSLayoutConstraint:0x7b360f00 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7b35c5e0(480)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7b35bfe0 H:[UIView:0x7b35c650(160)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
           

回顧我們之前的幾節,我們需要為自動布局提供足夠的限制讓其計算所有view的位置和大小。現在我們的問題是,限制太多了“Unable to simultaneously satisfy constraints",這就意味着我們的限制出現了沖突。

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

綠色view現在有6個限制,4個間距限制(1-4)和2個長寬限制(5-6)。問題在哪裡呢?

在垂直模式下,沒有問題,因為父view的寬度為320。把水準方向的限制加起來正好為320:

16 + 0 + 160 + 128 + 16 = 320

但是在水準模式下,父view的寬度為568,這些限制之和是多少呢?

16 + 0 + 160 + 128 + 16 + ? = 568

這裡有248個額外的電沒有限制,自動布局不知道該怎麼辦了。這裡的沖突就在于,綠色view的寬度和水準間距。它們之間必須有其中一個是動态可變的。要麼是寬度可變,要麼是水準間距可變。我們期望的是綠色view大小固定,那麼就需要把trailing水準間距限制删掉。同理,trailing垂直間距限制也需要被删掉:

删掉後,storyboard效果如下:

iOS 自動布局 Auto Layout 入門 05 相冊 (上)

這樣,無論在水準模式還是垂直模式,綠色view的大小和位置都是我們所期望的了。

iOS 自動布局 Auto Layout 入門 05 相冊 (上)
iOS 自動布局 Auto Layout 入門 05 相冊 (上)

轉載請注明出處:http://blog.csdn.net/yamingwu/article/details/44205187