繼續UIImageView - BNR篇。html
經過Homepwner TARGETS -> General -> Deployment Info -> Devices中的iPhone改成Universal。當在iPad上運行時,自定義的細節界面不能自動調整大小來適應iPad的屏幕大小。所以,需使用Auto Layout來改變其顯示方式。canvas
一個約束(constraint)定義了視圖層級間特定的關係,其能夠用來決定一個或多個視圖的佈局。app
視圖校準矩陣的佈局屬性:框架
對於BNRDetailViewController.xib文件中,給底部的toolbar添加約束:iphone
1)toolbar的底邊緣跟最鄰近的單元相距0點(其爲toolbar的容器,即BNRDetailViewController視圖);工具
2)toolbar的左邊緣跟最鄰近的單元相距0點;佈局
3)toolbar的右邊緣跟最鄰近的單元相距0點;字體
4)toolbar的高度應爲44點。ui
打開BNRDetailViewController.xib文件,點擊圖中的左數第三個pin按鈕,按下圖添加約束:spa
在上圖中,在Spacing to nearest neighbor部分,點擊紅色虛線,變成紅色實現,即添加了一個距離約束。並將Height左邊的方框打鉤,給Height添加約束。最後,點擊底部的Add 4 Constraints使添加的約束生效。
當建立了一個約束時,它將被添加到視圖層級中特定的視圖對象上。該約束影響了那個視圖,則該視圖就擁有這個約束。
按下圖給Name標籤添加約束:
按下圖給Name右邊的field添加約束:
接着,選中Name標籤和該field,點擊圖中的左數第二個Align圖標,以下,給Baselines添加約束:
每個約束都有一個優先級(Priority level),其用於當約束髮生衝突時,哪一個約束會獲勝。優先級從1到1000,1000是必須的一個優先級。
約束調試:
Ambiguous layout——意味着至少缺乏一個約束。
在BNRDetailViewController.xib文件中添加兩個Label,以下圖:
選中兩個Label,按照添加約束下圖添加top、left、right約束:
在BNRDetailViewController.m文件中添加viewDidLayoutSubviews方法以下:
1 //當視圖改變大小時自動被調用(如第一次在屏幕上顯示,或屏幕旋轉) 2 - (void)viewDidLayoutSubviews { 3 //檢查子視圖是否有任何模凌兩可的佈局 4 for(UIView *subview in self.view.subviews) { 5 if ([subview hasAmbiguousLayout]) { 6 NSLog(@"AMBIGUOUS: %@", subview); 7 } 8 } 9 }
運行程序,將報告兩個label的佈局是模凌兩可的。
修改backgroundTapped:方法以下:
1 - (IBAction)backgroundTapped:(id)sender { 2 [self.view endEditing:YES]; 3 4 for(UIView *subview in self.view.subviews) { 5 if ([subview hasAmbiguousLayout]) { 6 [subview exerciseAmbiguityInLayout]; 7 } 8 } 9 }
當點擊背景視圖時,模凌兩可的兩個label將互相轉換。
從一個labelControl-Drag到另外一個label,選中Equal Widths,使兩個label的寬度相等。
exerciseAmbiguityInLayout方法純粹是調試的工具,容許Auto Layout向你展現可能存在的佈局。不該將該代碼留在程序中。
Unsatisfiable constraints:當兩個或更多個約束衝突時發生。意味着一個視圖約束太多。
Misplaced Views:在XIB文件中視圖的位置與其約束不匹配。意味着程序運行時,視圖的框架跟在畫布(canvas)上顯示的不同。
在不一樣的設備上,爲了使視圖控制器加載恰當的XIB文件,能夠給xib文件加後綴,文件名爲 BNRDetailViewController~iphone.xib BNRDetailViewController~ipad.xib 。
可是,該方法不能替代Auto Layout。Auto Layout亦會對用戶的語言、字體大小或設備朝向做出反應。