李嵐 李可嘉
摘 要:iOS中的Autolayout技術(shù)用于解決UI可視單元或元素的布局和排列問題并且能夠可以完美的解決適配不同尺寸的屏幕以及解決橫豎屏的問題,讓編程不再枯燥無味,因此被越來越多的編程者所接受,Autolayout中的核心基礎(chǔ)是約束,介紹了Autolayout中約束的研究意義,約束的類型和優(yōu)先級,ContentSize約束,約束的裝載方式和比較,最后對約束的使用提出了幾點(diǎn)建議。
關(guān)鍵詞:iOS;Autolayout;研究
1 Autolayout中約束的研究意義
Autolayout自動布局技術(shù)在iOS6就已經(jīng)推出了,但是因?yàn)楹芏嗳艘婚_始不習(xí)慣使用xib編程,而是堅(jiān)持使用代碼布局控件,所以Autolayout并沒有普及的太快。但是現(xiàn)在隨著越來越多的人開始使用xib,怎樣適配橫豎屏和不同尺寸的屏幕,成了亟待解決的問題,好在兩年前就已經(jīng)推出并且日臻完善的xib Autolayout技術(shù)可以完美的解決。對于Autolayout而言,最為核心的基礎(chǔ)就是約束。
2 Autolayout中約束的類型
對于Autolayout而言,最為核心的基礎(chǔ)就是約束,在iOS 中分別有以下幾類約束:
NSLayoutConstraint,開放類。幾乎是程序員最常用的約束。它用于設(shè)置view在view tree之間的關(guān)系,自身大小等。
NSContentSizeLayoutConstraint,私有類。用于衡量view內(nèi)容和大小相關(guān)的約束。比如Hugging和Compression,控制view的內(nèi)容顯示。
NSAutoresizingMaskLayoutConstraint,私有類。由Autosizing mask轉(zhuǎn)換到Autolayout系統(tǒng)中的約束表達(dá)。
_UILayoutSupportConstraint,私有類。布局支撐約束,它包括Top和Bottom的約束,用于控制view的顯示邊界,例如,它限制view的頂端顯示不會和狀態(tài)欄重合。
NSIBPrototypingLayoutConstraint,私有類。如果在Storyboard中添加了一個(gè)UI控件,且沒有在Storyboard中添加任何約束,但是標(biāo)注了要使用Autolayout,那么在實(shí)際的運(yùn)行期,系統(tǒng)會默認(rèn)為它添加NSIBPrototypingLayoutConstraint約束。
NSContentSizeLayoutConstraint最主要的作用是和intrinsic size一起工作,通常這個(gè)約束和Layout約束共同決定view的顯示方式。
3 Autolayout中約束優(yōu)先級
約束優(yōu)先級通常是形容一個(gè)約束重要性的指標(biāo),兩個(gè)約束如果共同決定一個(gè)顯示屬性的顯示,當(dāng)二者發(fā)生了抵觸的時(shí)候,優(yōu)先級表示其中一個(gè)約束,相比另外一個(gè)而言,更加重要。優(yōu)先級就是浮點(diǎn)數(shù),通常用其整數(shù)表達(dá)。
4 ContentSize約束
Autolayout系統(tǒng)有根據(jù)顯示內(nèi)容來自適應(yīng)尺寸的能力。這個(gè)能力是由,Intrinsic Content Size內(nèi)容大小、content hugging約束、content compression約束來共同決定。
Intrinsic Content Size保證了當(dāng)view的內(nèi)容變化后,自己適應(yīng)內(nèi)容的大小的描述。自定義View需要自己計(jì)算適合自己的intrinsic size。而imageview、label等含有內(nèi)容控件(除了UITextView)都會自己計(jì)算“適合內(nèi)容的Size”。
Content Hugging抗拉伸屬性。它其實(shí)是一個(gè)約束,它使得它本身的大小更加貼合顯示的內(nèi)容。例如:如果一個(gè)UIView的內(nèi)容顯示需要200的寬度,那么如果UIView本身有寬度約束(此約束設(shè)置寬度為400),此時(shí)若抗拉伸屬性的優(yōu)先級比寬度約束要高,View本身的大小就不會變化,反之就會被拉伸。
Compression Resistance抗壓縮屬性。它的一切和抗拉伸相反。
Layout Constraints Layout約束是程序員必須熟悉的。一個(gè)線性公式就說明了它的意義:
view1.attr1=view2.attr2*multiplier + constant
這里=可以是>=,<=,<,>等。
剩余就是描述Layout Constraint的生成和裝載方式:
生成方式比如:Layout Constraints的描述方式可以是原生NSLayoutConstraint來實(shí)現(xiàn),也可以是VFL,也可以是自己封裝的庫。
5 Autolayout中約束的裝載方式
(1)View形容它自己的約束(一元約束),添加到自己或者直系SuperView中。(2)View和View之間的約束,如果view之間是父子關(guān)系,添加到父親上。如果view和view是兄弟關(guān)系,則添加到他們共同的父親節(jié)點(diǎn)上。(3)View和View之間的約束,如果他們是兩個(gè)不同的分支上的,則需要把約束添加到他們共同的祖先上面。
6 Autolayout中約束的比較
通常而言,比較對象,需要比較一個(gè)對象的所有成員變量。如果一一相等,則表明他們相等。但是,對于約束而言,這個(gè)比較方式比較例外:除了優(yōu)先級以外的參數(shù)都要一致,才是一樣的約束。也就是說優(yōu)先級是不需要參與比較的。例如:
-(BOOL) isEqualToConstraint:(NSLayoutConstraint*) constraint
{
if (self.firstItem != constraint.firstItem) return NO;
if (self.secondItem != constraint.secondItem) return NO;
if (self.firstAttribute != constraint.firstAttribute) return NO;
if (self.secondAttribute != constraint.secondAttribute) return NO;
if (self.relation != constraint.relation) return NO;
if (self.multiplier != constraint.multiplier) return NO;
if (self.constant != constraint.constant) return NO;
return YES;
}
7 Autolayout中約束使用的幾個(gè)建議
(1)充分利用約束的優(yōu)先級。不要把所有約束的優(yōu)先級都設(shè)置成Require。(2)約束沒有順序而言。優(yōu)先級越高越會得到滿足。(3)注意UpdateConstraint、Layoutsubview、DrawRect的順序,在這個(gè)管線中的特定階段做想自定義的事情。(4)注意約束描述的合理性,以避免自我矛盾的描述引起的Layout約束的沖突、歧義甚至崩潰。
參考文獻(xiàn)
[1]Erica Sadun ,iOS Auto Layout Demystified,Second Edition[M].Addison-Wesley Educational Publishers Inc; 2nd Revised edition ,2013.
[2]關(guān)東升.iOS開發(fā)指南:從零基礎(chǔ)到App Store上架(第2版)[M].人民郵電出版社,2014.