
約束既可以定義布局屬性的具體值,也可以定義布局屬性之間的關(guān)系
UIToolbar對(duì)象在不同屏幕中的布局方式:
?UIToolbar對(duì)象應(yīng)該始終位于屏幕底部。
?UIToolbar對(duì)象的寬度應(yīng)該和屏幕寬度保持相等?! ?br>
?UIToolbar對(duì)象的高度始終是44點(diǎn)。(Apple建議的UIToolbar標(biāo)準(zhǔn)高度。)
將文本框與Name標(biāo)簽沿基準(zhǔn)線對(duì)齊。這樣當(dāng)用戶(hù)輸入文字時(shí),文本框中的文字會(huì)與Name標(biāo)簽中的文字位于同一基準(zhǔn)線上,看起來(lái)會(huì)非常整齊。
在畫(huà)布中選中文本框,然后按住Shift鍵不放,選中Name標(biāo)簽。這樣可以同時(shí)選中文本框和Name標(biāo)簽。接下來(lái)在約束菜單中點(diǎn)擊圖標(biāo),顯示Align(對(duì)齊)菜單,再勾選標(biāo)題為Baselines的選擇框,最后點(diǎn)擊Add1Constraint添加約束。
優(yōu)先級(jí)
每個(gè)約束都具有優(yōu)先級(jí)(prioritylevel),如果多個(gè)約束之間有沖突,自動(dòng)布局系統(tǒng)會(huì)根據(jù)優(yōu)先級(jí)決定使用哪些約束。優(yōu)先級(jí)的取值范圍是1到1000,默認(rèn)值是1000,表示約束是必需(requiredconstraint)的。因此,之前添加的約束都是必需的,優(yōu)先級(jí)都是1000,如果這些約束之間存在沖突,優(yōu)先級(jí)無(wú)法幫助自動(dòng)布局系統(tǒng)解決約束沖突。
調(diào)試約束問(wèn)題
有歧義的布局
有歧義的布局(ambiguouslayout)是指自動(dòng)布局系統(tǒng)無(wú)法根據(jù)當(dāng)前約束確定視圖的所有布局屬性,該問(wèn)題通常是由于視圖缺少約束。
為了進(jìn)一步知道視圖缺少哪種約束,可以查看自動(dòng)布局系統(tǒng)推測(cè)的另一種布局方式。在加載該視圖的controller中修改backgroundTapped:方法,向有歧義布局的子視圖發(fā)送exerciseAmbiguityInLayout消息。
-(IBAction)backgroundTapped:(id)sender
{
[self.viewendEditing:YES];
for(UIView*subviewinself.view.subviews)
{
if([subviewhasAmbiguousLayout])
{
[subviewexerciseAmbiguityInLayout];
}
}
}
構(gòu)建并運(yùn)行應(yīng)用,進(jìn)入該視圖,然后點(diǎn)擊視圖任意位置,這時(shí)會(huì)發(fā)現(xiàn)異常。如果再次點(diǎn)擊,又會(huì)異常消失。
請(qǐng)讀者記住,exerciseAmbiguityInLayout方法僅僅是用來(lái)調(diào)試約束問(wèn)題的工具,用來(lái)查看自動(dòng)布局系統(tǒng)在有歧義布局情況下的各種布局效果——發(fā)布應(yīng)用時(shí),不要使用該方法。
無(wú)法滿(mǎn)足的約束
如果為視圖添加了不必要的約束,就可能造成多個(gè)約束之間發(fā)生沖突,自動(dòng)布局系統(tǒng)無(wú)法同時(shí)滿(mǎn)足這些約束。
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
視圖位置錯(cuò)誤
如果視圖在XIB文件中的frame與自身約束不一致,就會(huì)發(fā)生視圖位置錯(cuò)誤。視圖位置錯(cuò)誤是指視圖在運(yùn)行時(shí)的frame與其在畫(huà)布中的frame不同。

標(biāo)簽原來(lái)的位置會(huì)出現(xiàn)一個(gè)橘紅色虛線邊框的矩形,這是標(biāo)簽在運(yùn)行時(shí)的frame。自動(dòng)布局系統(tǒng)在運(yùn)行時(shí)會(huì)根據(jù)約束將標(biāo)簽移動(dòng)到該矩形的位置,而不是剛才拖曳后的位置。
這類(lèi)錯(cuò)誤有兩種解決方案,取決于視圖在畫(huà)布上的frame是否符合要求。如果要求視圖在運(yùn)行時(shí)的frame與畫(huà)布上的frame相同,就修改視圖的約束,匹配當(dāng)前frame;反之,就修改視圖的大小或位置匹配當(dāng)前約束。對(duì)于date標(biāo)簽,畫(huà)布上的frame不符合要求,需要移動(dòng)date標(biāo)簽匹配當(dāng)前約束。
選中date標(biāo)簽,然后在畫(huà)布右下角的約束菜單中點(diǎn)擊圖標(biāo),顯示ResolveAutoLayoutIssues(解決自動(dòng)布局問(wèn)題)菜單:

使用_autolayoutTrace方法調(diào)試約束問(wèn)題
之前通過(guò)遍歷并依次發(fā)送hasAmbiguousLayout消息的方式來(lái)查找有歧義布局的視圖。如果這些視圖都是視圖控制器view的一級(jí)子視圖,那么遍歷一次就可以找出全部視圖,但是,如果這些視圖中又包含復(fù)雜的視圖層次結(jié)構(gòu),就應(yīng)該使用另一種方法。
UIWindow有一個(gè)名為_(kāi)autolayoutTrace的私有實(shí)例方法,該方法返回一個(gè)表示UIWindow中整個(gè)視圖層次結(jié)構(gòu)的字符串。對(duì)于有歧義布局的視圖,_autolayoutTrace會(huì)使用AMBIGUOUSLAYOUT(有歧義的布局)標(biāo)記出來(lái)。
使用該方法的最好方式是在顯示視圖的代碼(如視圖控制器的viewWillAppear:方法)中設(shè)置一個(gè)斷點(diǎn),當(dāng)程序在斷點(diǎn)處停下來(lái)之后,在控制臺(tái)中輸入以下代碼,然后按下Enter鍵:po [[UIWindow keyWindow] _autolayoutTrace];
如果應(yīng)用界面與期望的布局方式不一致,同時(shí)也無(wú)法確定問(wèn)題原因,就可以使用該方法找出有歧義布局的視圖。
使用多個(gè)XIB文件
XIB文件的命名規(guī)則,針對(duì)iPhone和iPad的XIB文件需要在類(lèi)名后加上對(duì)應(yīng)的后綴:
BNRDetailViewController~iphone.xib
BNRDetailViewController~ipad.xib
現(xiàn)在,BNRDetailViewController可以在運(yùn)行時(shí)根據(jù)設(shè)備類(lèi)型自動(dòng)加載后綴為iphone或ipad的XIB文件。