Autolayout各個名詞的解釋 <br >
來自:《Programing.iOS.9.2015.11》59-61頁
所有代碼均在github上
Autolayout
AutoLayout對于每一個單獨(dú)的view層次上是一個可選的技術(shù)娇唯。一個view可以在以下三種方式下選擇Autolayout阀捅。
你在代碼中給一個view添加Autolayout約束攀操。在這個約束下的view使用Autolayout。
你的app加載一個“Use Auto Layout”勾選的nib芯急,每一個通過nib實例的view都使用了autolayout。
-
一個在interface下的view驶俊,而且它是你自定義的UIView的子類志于,在這個類方法
requiresConstraintBasedLayout
返回true,這個view也使用了Autolayout废睦。你通過第三種方式選擇Autolayout的原因可能是你想要將Autolayout轉(zhuǎn)換伺绽,來在代碼中使用Autolayout constraints,一個通常的在代碼中創(chuàng)建contraints的方式是在一個view的updateContraints的實現(xiàn)里面嗜湃。但是如果Autolayout沒有Switched奈应,updateContraints不會被調(diào)用。所以說
requiresConstraintBasedLayout
提供了一種Switching on的方式购披。
一個同胞view可以使用autolayout杖挣,但是另一個同胞view可以不使用,一個superview可以使用Autolayout刚陡,但是一些或者他所有的子view可以不使用惩妇。
但是Autolayout被應(yīng)用到整個superview鏈,所以說如果一個view使用了Autolayout筐乳,
然后就自動應(yīng)用到他的整個superviews歌殃,同時如果其中的view之一是控制器的main view的話,控制器
會收到自動布局相關(guān)的事件蝙云,否則的話就不會收到氓皱。
你不可以對一個view的一部分關(guān)閉Autolayout。或者所有的來自nib實例化的view
使用了Autolayout波材,或者他們都使用了autoresizing股淡。為了生成不同部分的interface來自
不同的nibs,其中一部分使用了autoresizing廷区,另一部分使用了Autolayout唯灵,并且把這些不同的
部分分開到不同的nib(或者不同的Storyboard),然后在runtime里加載隙轻,編譯早敬。
Contraints
Autolayout contraint, 或者說簡單的contraint大脉,是一個NSLayoutContraint實例搞监,
它描述了一個view的絕對width和height,或者是一個view的屬性和另一個view的屬性關(guān)系镰矿。
在后一種情況下琐驴,這種屬性并不一定是相同的屬性,同時這兩個view也不一定是同胞關(guān)系或者父和子的關(guān)系秤标。
唯一的要求就是他們來自同一個祖先view绝淡。
這里有一些NSLayoutContraint主要的屬性:
-
firstItem
,firstAttribute
,secondItem
,secondAfttribute
這兩個view和他們各自的屬性(NSLaoyoutContraint)都和這個contraint有聯(lián)系。
如果這個contraint描述了一個view的height或者width苍姜,另一個view可能是nil牢酵,另一個屬性可能是
.NotAnAttribute
。其他的NSLayoutContraint有:-
.Top
,.Bottom
-
.Left
,.Right
,.Leading
,.Trailing
-
.Width
,.Height
-
.CenterX
,.CenterY
-
.FirstBaseline
,LastBaseline
.FirstBaseline
主要應(yīng)用于多個label之間衙猪,而且底部距離label的頂部有一定的距離馍乙。
.LastBaseline
指的是頂部距離底部有一定的距離。其他的屬性的含義是顯而易見的垫释,除了有可能想知道“l(fā)eading”和“trailing”的含義丝格,
他們就相當(dāng)于“l(fā)eft”“right”,而且他們會自動反向他們的含義是“right-to-left”棵譬。
在新的iOS9上显蝌,全部的interface已經(jīng)在系統(tǒng)上自動地反向了--但是這僅僅是當(dāng)你使用了“l(fā)eading”和“trailing”約束的時候。 -
multiplier
,constant
這兩個屬性會被應(yīng)用到第二個屬性值订咸,然后他來決定第一個屬性值曼尊。multiplier
用來乘上第二個屬性值,constant
被添加到這個積數(shù)中脏嚷。
第一屬性被用來設(shè)置結(jié)果The first attribute is set to the result.(這句話我也不懂是啥意思)骆撇,(constant是一個非常有限的選擇范圍,因為這個值并不是一個常數(shù)然眼。)
從根本上來講艾船,你寫了一個等式:a1=m*a2+c,其中a1和a2就是兩個屬性值葵腹,m和c是multiplier和constant高每。最壞的情況是
當(dāng)?shù)谝粚傩灾档扔诘诙傩灾涤炱瘢渲衜ultiplier等于1, constant等于0鲸匿。如果你想要絕對的描述一個view的width和height爷怀,multiplier等于1,同時constant等于width或者h(yuǎn)eight的值带欢。
-
relation
一個NSLayoutContraint說明了這兩個屬性值和另外一個屬性值之間的關(guān)系运授,就像被
multiplier和constant所修改的那樣。這就是在前一段中我在等號左右的操作乔煞。(.Equal
)
但是不平等(iindequality)也是允許的吁朦。(.LessThanOrEqual
,.GreaterThanOrEqual
) -
priority
優(yōu)先級值的范圍是從1000到1,同時確定標(biāo)準(zhǔn)的行為有標(biāo)準(zhǔn)的優(yōu)先級渡贾。約束可以有不同的優(yōu)先級逗宜,來確定他們使用的順序。
一個約束屬于一個view空骚,同時一個view也可以有很多的約束纺讲。一個UIView添加一個約束屬性可以有一下幾種實例方法:<br />
.addConstraint:
, addConstraints:
<br >
.removeConstraint:
, removeConstraints:
<br >
存在的問題是約束屬于哪一個view。答案是:最接近參與約束的兩個視圖層次結(jié)構(gòu)的視圖囤屹。
如果可能的話熬甚,那應(yīng)該是這些view其中之一。舉個例子來說肋坚,如果一個view講述了一個view的width乡括,
那它就屬于這個view,如果它設(shè)置了這個view頂部的距離到他的父view頂部的距離的話智厌,它就屬于父view粟判,
如果他校準(zhǔn)了兩個同胞view,那這個約束就屬于他們共同的父view峦剔。<br >
從iOS8開始档礁,除了給一個特定的view添加明確的約束,你可以觸發(fā)約束使用NSLayoutContraint
類方法activateContraints:
這個方法會取得所有約束的數(shù)組吝沫。被觸發(fā)的約束也會被自動地添加到正確的view上呻澜。還有一個方法deactivateContraints:
,他會移除該view所有的
約束惨险。約束有一個活躍的屬性羹幸,你可以設(shè)置它來觸發(fā)或者是關(guān)閉一個單獨(dú)的約束,同時再加上它可以告訴你
一個給定的約束是否為一個interface的一部分辫愉。<br >
說明:一旦你對一個view的position和size使用了明確的約束栅受,隨后不要設(shè)置他的frame(或者bounds和center)
只需要使用contraints就OK。否則的話,當(dāng)layoutSubviews
這個方法被調(diào)用的時候屏镊,這個視圖會跳回到原來他約束規(guī)定位置依疼。
(除非你在layoutSubviews
里設(shè)置一個view的frame,我會在以后介紹而芥。)
Autoresizing contraints
這個機(jī)制讓其中選擇了Autolayout的view可以在Autolayout層次上突然影響其他view律罢,即使其他的view之前沒有使用Autolayout。
所以說存在一種方式棍丐,當(dāng)一個view在Autolayout上被影響的同時來通過constraints來保證它的position和layout在之前通過frame和autoresizingMask確定那樣误辑。
這種方式就是runtime,它將view的frame和autoresizingMask轉(zhuǎn)換成約束歌逢。結(jié)果就是一些內(nèi)在的來自NSAutoresizingMasklayoutConstraint
的約束巾钉,影響這個view(當(dāng)然他還可能和其他的view有聯(lián)系)。
多虧了這個隱含的約束秘案,被這個view的autoresizingMask描述的布局才可以繼續(xù)工作睛琳。<br >
比如:加入我有一個UILabel,它的frame為(20.0, 20.0, 42.0, 22.0), 然后它的autoresingMask為.None踏烙。如果這個label突然使用了Autolayout师骗,
然后它的superview可能需要四個隱含的約束也就是設(shè)置它的width為42, height為22讨惩,它的centerX為41辟癌,它的centerY為31。<br >
這個結(jié)果僅僅在這個view的translatesAutoresizingMaskIntoConstraints
屬性設(shè)置為true的時候荐捻。
如果這個view已經(jīng)用代碼實現(xiàn)了或者是一個nib的實例化當(dāng)然nib的“Use Auto Layout”沒有被勾選的話黍少,上面就是默認(rèn)的。
上面的假設(shè)的條件是一個view使用其他的方式創(chuàng)建处面,如果他被涉及到Autolayout你想要它的frame和autoresizingMask像constraints一樣厂置。
這是個合理的規(guī)則,但是也意味著如果你打算給你的view應(yīng)用明確的約束魂角,你可能需要記住通過設(shè)置view的translatesAutoresizingMaskIntoConstraints為false來關(guān)閉自動的行為昵济。
如果你沒有這樣做,結(jié)果就是你的view中將包含隱含的約束和明確的約束野揪,這不可能是你想要的访忿。
按照傳統(tǒng)來講,這種情況往往會導(dǎo)致約束之間的沖突斯稳,(我會在下面解釋的)海铆。實際上,我們經(jīng)常會發(fā)生不記得去設(shè)置view的translatesAutoresizingMaskIntoConstraints屬性為false挣惰,
通常也是在我們得到一個約束之間沖突的時候被提醒到的卧斟。
下一篇:Create contraints in code
如有那些譯的不合理殴边,請隨時隨地聯(lián)系我。評論或下方聯(lián)系方式之一珍语。
github: qiuncheng (所涉及到的代碼均在github上可見)
weibo: iOS_BIG
email: <a href = "Mailto:qiuncheng@gmail.com">qiuncheng@gmail.com</a>
博客: qiuncheng.com