iOS AutoLayout
iOS AutoLayout
- Autolayout是一種全新的布局技術(shù),專門用來(lái)布局UI界面的,用來(lái)取代Frame布局在遇見(jiàn)屏幕尺寸多重多樣的問(wèn)題。Autolayout自iOS 6開(kāi)始引入,但是由于Xcode 4的不給力,當(dāng)時(shí)并沒(méi)有得到大規(guī)模推廣。在iOS 7(Xcode5)開(kāi)始,Autolayout的開(kāi)發(fā)效率得到很大的提升,蘋果官方也推薦開(kāi)發(fā)者盡量使用Autolayout來(lái)布局UI界面,減少純代碼的方式。在iOS6之前是用Autoresize布局.
- Autolayout的好處是能夠很方便的適配各種尺寸的屏幕,并且當(dāng)很好的適配屏幕的橫向和豎向,不會(huì)造成使用在有些手機(jī)上顯示不全,或者橫豎屏后布局錯(cuò)位的問(wèn)題.
- Autolayout父視圖去添加對(duì)子視圖的約束,Autoresize是子視圖添加都父視圖的相對(duì)位置和大小.
AutoLayout的使用
- AutoLayout常見(jiàn)的使用方式有兩種:
 1.IB方式即StoryBoard,Xib;
 2.純代碼方式即VFL,NSLayoutConstraint,Masonry,SnapKit.
1.IB方式實(shí)現(xiàn)自動(dòng)布局
-  在xib或者stroyBoard中添加約束的核心思想是一定要確定視圖的frame,不管是設(shè)置(Leading,Top,Width,Height),還是設(shè)置距離上下左右的間距都是為了確定視圖的farme,根據(jù)需求做不同的設(shè)置.如果是設(shè)置上下左右的間距固定,則視圖的尺寸會(huì)不同尺寸的手機(jī)顯示的大小不同,如果設(shè)置的是Width,Height以及Leading(或者Trailing),Top(或者Bottom),則實(shí)體的長(zhǎng)寬固定,而沒(méi)有添加約束的兩條邊的邊距根據(jù)手機(jī)的尺寸不同而不同.總至要至少要添加四條約束. 
-  但是有些控件添加兩條約束Leading(或者Trailing),Top(或者Bottom)也是可以的,如UILabel,UIimageView,UIButton,如果不設(shè)置寬高這些控件會(huì)根據(jù)內(nèi)容自動(dòng)調(diào)整大小.IB自動(dòng)布局大家都比較熟悉,這里就不再詳述. 
2.VFL/NSLayoutConstrais方式實(shí)現(xiàn)自動(dòng)布局
- VFL(Virsual Format Language)是一種虛擬的格式化語(yǔ)言,主要用來(lái)創(chuàng)建AutoLayout的約束字符串。
- VFL官網(wǎng)介紹
- VFL基本語(yǔ)法介紹:例如: "V:[view1]-0-[view2(==100@1000)]-<=0-|"
| 垂直方向 | V: | 
| 水平方向 | H: | 
| Views | [view1],[View2] | 
| SuperView | | | 
| 關(guān)系(不寫默認(rèn)==) | >=,==,<= | 
| 空間,間隙(不寫默認(rèn)值8) | - | 
| 優(yōu)先級(jí) | @value | 
- 示例:添加上中下三個(gè)視圖,上中視圖等高,下視圖距中間視圖底部的間隙8,并且占滿屏幕剩余部分.
- 給下面藍(lán)色視圖添加一個(gè)UILabel,使其上左右邊距為10,高度自適應(yīng)
- 刪除約束,更新布局
小結(jié)
- 上面可以看出:NSLayoutConstraint的constraints方法是通過(guò)VFL添加水平和垂直方向約束來(lái)進(jìn)行自動(dòng)布局,而NSLayoutConstraint的便利構(gòu)造方法是通過(guò)添加上下左右間距或間距和大小來(lái)添加約束來(lái)自動(dòng)布局,兩者單獨(dú)使用或結(jié)合使用都可以,各有優(yōu)缺點(diǎn),一般會(huì)結(jié)合使用.
-  oc 中 NSDictionaryOfVariableBindings(v1,v2,v3)宏相當(dāng)于[NSDictionary dictionaryWithObjectsAndKeys:v1,@“v1”,v2,@“v2”,v3,@“v3”,nil] 
-  父控件是誰(shuí),這些約束就添加給誰(shuí). 
-  UIView的open var translatesAutoresizingMaskIntoConstraints: Bool屬性,把 autoresizingMask 轉(zhuǎn)換為 Constraints,即:可以把 frame ,bouds,center 方式布局的視圖自動(dòng)轉(zhuǎn)化為約束形式。(此時(shí)該視圖上約束已經(jīng)足夠 不需要手動(dòng)去添加別的約束). 
-  用代碼創(chuàng)建的所有view , translatesAutoresizingMaskIntoConstraints 默認(rèn)是 true,用 IB 創(chuàng)建的所有 view ,translatesAutoresizingMaskIntoConstraints 默認(rèn)是 false . 如果用代碼約束布局,則需要將該屬性設(shè)置為false. 
-  translatesAutoresizingMaskIntoConstraints屬性autoresize布局:true,autolayout布局 :false`. 
-  在更新約束時(shí),要先刪除一些約束removeConstraints,再添加對(duì)應(yīng)的一些約束addConstraints,然后跟新約束才有有效. 
-  項(xiàng)目開(kāi)發(fā)過(guò)程中,通常使用的是Masonry\SnapKit自動(dòng)布局的三方庫(kù),簡(jiǎn)單高效。較之frame布局,自動(dòng)布局更適合業(yè)務(wù)拓展。 
基于約束的AutoLayer更新約束的方法
1、setNeedsUpdateConstraints
 當(dāng)一個(gè)自定義view的某個(gè)屬性發(fā)生改變,并且可能影響到constraint時(shí),需要調(diào)用此方法去標(biāo)記constraints需要在未來(lái)的某個(gè)點(diǎn)更新,系統(tǒng)然后調(diào)用updateConstraints.
 2、needsUpdateConstraints
 constraint-based layout system使用此返回值去決定是否需要調(diào)用updateConstraints作為正常布局過(guò)程的一部分。
 3、updateConstraintsIfNeeded
 立即觸發(fā)約束更新,自動(dòng)更新布局。
 4、updateConstraints
 自定義view應(yīng)該重寫此方法在其中建立constraints. 注意:要在實(shí)現(xiàn)在最后調(diào)用[super updateConstraints]
 uto Layout Process 自動(dòng)布局過(guò)程
 與使用springs and struts(autoresizingMask)比較,Auto layout在view顯示之前,多引入了兩個(gè)步驟:updating constraints 和laying out views。每一個(gè)步驟都依賴于上一個(gè)。display依賴layout,而layout依賴updating constraints。 updating constraints->layout->display
 第一步:updating constraints,被稱為測(cè)量階段,其從下向上(from subview to super view),為下一步layout準(zhǔn)備信息。可以通過(guò)調(diào)用方法setNeedUpdateConstraints去觸發(fā)此步。constraints的改變也會(huì)自動(dòng)的觸發(fā)此步。但是,當(dāng)你自定義view的時(shí)候,如果一些改變可能會(huì)影響到布局的時(shí)候,通常需要自己去通知Auto layout,updateConstraintsIfNeeded。
 自定義view的話,通常可以重寫updateConstraints方法,在其中可以添加view需要的局部的contraints。
 第二步:layout,其從上向下(from super view to subview),此步主要應(yīng)用上一步的信息去設(shè)置view的center和bounds。可以通過(guò)調(diào)用setNeedsLayout去觸發(fā)此步驟,此方法不會(huì)立即應(yīng)用layout。如果想要系統(tǒng)立即的更新layout,可以調(diào)用layoutIfNeeded。另外,自定義view可以重寫方法layoutSubViews來(lái)在layout的工程中得到更多的定制化效果。
 第三步:display,此步時(shí)把view渲染到屏幕上,它與你是否使用Auto layout無(wú)關(guān),其操作是從上向下(from super view to subview),通過(guò)調(diào)用setNeedsDisplay觸發(fā),
 因?yàn)槊恳徊蕉家蕾嚽耙徊?#xff0c;因此一個(gè)display可能會(huì)觸發(fā)layout,當(dāng)有任何layout沒(méi)有被處理的時(shí)候,同理,layout可能會(huì)觸發(fā)updating constraints,當(dāng)constraint system更新改變的時(shí)候。
 需要注意的是,這三步不是單向的,constraint-based layout是一個(gè)迭代的過(guò)程,layout過(guò)程中,可能去改變constraints,有一次觸發(fā)updating constraints,進(jìn)行一輪layout過(guò)程。
 注意:如果你每一次調(diào)用自定義layoutSubviews都會(huì)導(dǎo)致另一個(gè)布局傳遞,那么你將會(huì)陷入一個(gè)無(wú)限循環(huán)中。
相關(guān)參考
-  VFL的簡(jiǎn)單使用教程 
-  iOS-手動(dòng)添加限制-constraintsWithVisualForm 
-  translatesAutoresizingMaskIntoConstraints 詳解 
-  自動(dòng)布局之-NSLayoutConstraint 
-  Autoresize和Autolayout 布局的實(shí)現(xiàn) 
-  iOS AutoLayout全解 
-  setNeedsUpdateConstraints,needsUpdateConstraints等基于約束的AutoLayer的方法 
-  ios – setNeedsLayout vs. setNeedsUpdateConstraints and layoutIfNeeded vs updateConstraintsIfNeeded 
-  MY_updateConstraintsIfNeeded,setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之間的關(guān)系解釋 
-  iOS自動(dòng)約束】四個(gè)重要的系統(tǒng)方法 
-  UIStackView 
-  Stack 
-  相關(guān)源碼(包括AutoLayout,Masonry,SnapKit):AutoLayoutStudy 
總結(jié)
以上是生活随笔為你收集整理的iOS AutoLayout的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 机器学习实战 利用sklearn库预测科
- 下一篇: spring 多线程 事务 源码解析(一
