學會愛上iOS自動布局(Auto Layout)


本文翻譯自Yari Dareglia的LEARN TO LOVE AUTO LAYOUT文章

先生們,女士們,讓我們以正確的心態開始本教程吧:自動布局就是簡單!

我花了一段時間來掌握自動布局是如何工作的,現在回頭看,我發現我絕對是高估了這個問題。在這篇文章中我將介紹一些基本的方面和一些技巧,我敢肯定會幫助你在面對自動布局時不在害怕。

Xcode4


在Xcode5之前,自動布局可能是你在你的應用中實現的最討厭的“功能”。標記“使用自動布局”就像說“把我變瘋吧”。這就是為什么我從來沒有對這個標記打勾。為自己感到可恥!

但是在Xcode5中,情況變得完全不同了,如果你仍然對Xcode4中的自動布局做惡夢,好了,忘記他們!

簡單描述一下自動布局


通過自動布局,你可以利用UI元素之間的關系來組織你應用的界面。這些關系稱為約束。

一開始,這聽起來很難懂,因為我們都是獨立放置每個子視圖的,僅僅需要考慮修改frame/bound屬性來決定子視圖在哪里以及怎么繪制即可。

這就是本文的第一個目標:拋棄過時落后的習慣!

介紹Xcode5中自動布局的界面


我們可以通過代碼或者Interface Builder工具的幫助來設置自動布局的關系。我會在接下來的例子中介紹代碼的形式設置自動布局,但現在我們只是介紹Xcode提供的可視化設置界面,從而讓事情變得簡單些。

創建一個新的iOS工程,打開故事板(storyboard)。在右下角你可以看到一組關於自動布局的按鈕。我會在下面的代碼中解析其中這些按鈕的作用,現在僅僅記住這些按鈕是關於自動布局的即可。

另一種方法是直接通過視圖來與自動布局交互。把一個UIView拖動到視圖控制器上后,按ctrl +單擊UIView並拖動鼠標 。你應該看到一個藍色的選擇。你已經對這些很熟悉了,因為它跟我們用來連接IBOutlet/ IBAction是一樣的,但是這個時候如果你在新的視圖里面(也就是剛剛拖動的UIView里面)釋放它,你會看到一些新的選擇。

讓我們為剛剛創建的視圖添加一個約束。

*1. Crtl+點擊視圖的上面

*2.拖動鼠標保持一個水平軌跡。這確保了“寬度”參數顯示出來。當你在同一個視圖中釋放鼠標按,你可以嘗試垂直移動,以獲得高度參數(我個人覺得這種行為是具有良好的用戶體驗的一種選擇)。

*3.選擇“寬度(Width)”參數

現在,您已經創建了一個約束,意思是:“這個視圖的寬度是多少”。不必理會被繪制在視圖中的紅色/橙色線。我們只需要這個約束來看看一些其他的Xcode功能。

選擇這個UIView,並在右邊欄打開Size Inspector控制面板

你會發現一個叫約束的新區域,在我們的例子中包含了我們剛剛添加的寬度約束。

注意:有些時候,你不會看到寬度或高度約束參數,而是發現一個“Leading space to”的東西,這只是一個bug,取消選擇,再重新選擇對應的視圖,就可以獲取正確的參數。

從這里開始,你可以通過旁邊的設置圖標來修改這個約束或者刪除約束。

另一個你可以找到關於你的約束的信息可以在文檔大綱中找到,在故事板的左邊,你可以通過點擊下面的按鈕來開啟這個欄目

正如你說看到的,我們可以完全瀏覽所有剛剛創建的約束。點擊它,約束將在視圖編輯器中高亮顯示。
我們從文檔大綱中得到的另一個有用的信息是,設置的約束是否有不一致或者錯誤。在文檔大綱右上角出現的紅色圓圈和白色箭頭告訴我們,有些約束沒有設置正確。

點擊那個箭頭,一個新視圖會顯示出來並展示相關的細節和錯誤。

只要按一下第一個紅點。 Xcode足夠聰明得會建議你正確的自動布局配置。點擊“添加缺少約束”,Xcode會自動將一些約束參數添加到視圖中,所有的錯誤都將消失。

如果你再次點擊這個視圖,你會看到你的約束,但這時這些約束將會變成藍色。這意味着所有所需的約束都已經定義完成,自動布局完全明白怎么繪制你的視圖。

例子0:介紹約束


現在你知道如何與Xcode交互,以管理約束,我們可以使用自動布局練習和學習它是如何工作的。

我們應該牢記的主要規則是,通過自動布局指定一個視圖的位置,我們需要給它的X / Y位置和寬度/高度尺寸的約束。這是正常工作的第一步。

打開本教程的工程文件,並檢查主故事板的Example_0 Result控制器。您可以通過文檔大綱窗口來輕松地在所有的實例中切換。

這是第一個例子的最終結果:一個UIView在垂直和水平方向始終處於中心位置,而不管屏幕的大小的旋轉方向。

現在,您可以創建自己的項目或者干脆用我的(你可以在文章的末尾找到源代碼)。在這里,我已經創建本教程(命名EXAMPLE_N START)的所有例子和最終結果(名為EXAMPLE_N結果)的初始設置。

把眼光移到 EXAMPLE_0 START

*1.在這里,你可以找到一個作為主視圖的子視圖的黃色UIView。我設置了視圖大小為150X150,我把它放在X 85和Y209(只是跟着藍色導航線)。
我喜歡的做法是:在添加任何約束之前,我們定義視圖的大小和位置。只有在這些初始設置完成后,才開始設置約束。

*2.現在,讓我們使用2種不同的方法來添加尺寸約束。 正如我們在上一節中所做的,CTRL +單擊新的視圖和水平拖動鼠標來添加寬度約束。

現在,加入高度約束,我們可以使用右下角的圖標。首先選擇黃色的UIView,然后單擊帶有“+”標志的“高度”參數的圖標,然后單擊“添加約束”按鈕。這只是另一種方式來設置一個約束。

我們已經定義了這個大小約束了。

*3.在文檔大綱中點擊紅色圓圈,來獲取關於我們的視圖設置的問題。

正如我所說的,我們需要設置寬度/高度和X / Y以符合自動布局要求的條件,同時Xcode也會幫助我們強調當前還有什么沒有設置。

我們可以叫Xcode幫我們自動解決這些錯誤,與我們之前點擊“添加缺少約束”按鈕或者是手動添加效果一樣。這次就讓我們手動添加吧,來看看怎么在父視圖和子視圖之間創建關系。

同樣,我們可以選擇兩種方式來添加約束:

Ctrl+ 點擊UIView視圖,但這次是把鼠標保持垂直軌跡來拖動到這個視圖的父視圖才釋放。

選擇“Center horizontally in the container”。你可以在名叫“align Center X to: Superview”的大小檢查器中驗證這個新的約束。

為了添加垂直(Y)的約束,我們使用顯示對齊約束選項的第一個圖標。點擊這個按鈕,勾選“Vertical center in container”標記,最后點擊“Add Constraints”來確認添加。

你應該看到兩個新的藍色線穿過這個視圖,現在所有所需的約束都已經創建了。

*4.啟動應用,並在橫屏和豎屏的模式之間切換。

太好了,黃色視圖都停留在中心位置。

(你可以通過去掉約束來查看之間的不同,在橫屏模式下,這個視圖會跑到屏幕外面去。)

Xcode幫助


另一個有趣的特點是Xcode在自動管理你的自動布局設置時所具有的重置frames和約束的能力。

在之前設置的約束中,移動黃色視圖到一個新的位置(僅僅在大小設置面板中輸入X=120,Y=240,而不需要改變約束)。你應該看到類似下面的畫面:

你的位置約束變成了橙色,代表這個視圖錯位了,一個紅色的,高亮的虛線正方形表示視圖期望的位置,而兩個標簽顯示當前視圖與期望視圖位置的距離。

在文檔大綱中,可以看到很多信息,這時指示器不是紅色了,而是橙色,表明這是視圖錯位是一個警告,而不是錯誤。事實上,自動布局約束仍然有效,即使你所看到的故事板的內容和運行的結果不同。

那么,我們怎么解決這個問題呢?首先你需要確定你想要的結果是什么。

你希望保持原始的設置嗎

如果是,點擊下面的按鈕:

然后選擇“update frame”,這個視圖會移動到運行時的位置(紅色虛線的位置)。

你希望更新運行時的位置嗎?

這種情況,同樣點擊上面的按鈕,選擇“update constraints”來改變約束適應當前的位置。

動手試試,看看兩者之間的不同吧。

例子1:固定內容大小


好了,轉到EXAMPLE_1_RESULT視圖控制器。

在這個例子中,我們希望用UILabel來獲得像EXAMPLE_0的結果。

移到EXAMPLE_1 START,然后僅僅添加一個位置約束(如果發現自己不知怎么做,可以回去查看上面例子的第三個步驟)。

是的,你完成了!你可以通過啟動應用來檢查結果。這個標簽完全放在窗口的中間。

等一下,你可能會問,那大小約束不用像上面那樣設置嗎?是的,我們不需要!而且,設置大小約束將被視為錯誤。

類似按鈕和標簽這些對象,是根據他們的內容來決定大小的。一個特定的方法 intrinsicContentSize 會返回這類視圖的大小信息,所以你不需要通過約束來覆蓋這些信息。

在這個教程中,我們不討論自定義視圖的自動布局,但是,如果你想創建一個自動適應大小的視圖,你應該更深入地理解這個方法。

例子2:與屏幕尺寸獨立的UI


當我們為3.5寸和4寸屏幕創建視圖,或者為橫屏和豎屏創建約束時,都會不同。

轉到EXAMPLE_2 RESULT。我想像你展示一個真的很普遍的情況:設置一個可以在任何屏幕尺寸和屏幕方向下都可以正常工作的布局。

分別在iPhone4和iPhone5下運行應用,並改變屏幕方向。你將看到布局都完美地適應屏幕的大小。

你已經知道怎么把一個標簽放在中間了,但是那個在屏幕底部的藍色視圖呢?讓我們轉到EXAMPLE_2 START。你可以如練習中那樣設置這個標簽,而這個藍色視圖有兩個我們必須考慮的方面:

  • 它的寬度根據屏幕的大小而改變
  • 他貼在屏幕的底部

讓我們記住的第一條規則,我們必須同時滿足的位置和大小的約束。

*1.首先第一件事情,通過移動屏幕底部的藍色視圖設置所需的位置。

*2.我們可以輕松地設置高度約束只是(按Ctrl+單擊)垂直拖動視圖並選擇“高度”或底部的圖標,因為我之前已經向您展示了。

*3.那寬度呢?我們希望它與父類視圖有關系,為了做到這點,我們需要創建兩個關系:

*保持它的左邊與父類的左邊距離在N的距離
*保持它的右邊與父類的右邊距離在N的距離

這兩個關系會根據它父類的大小變化而自動設置它的寬度。

為了創建這些關系,我們可以Ctrl+點擊藍色視圖,移動到左邊的父類視圖中釋放,同時選擇“ leading space to container”以及在右邊選擇“trailing space to container.”。

這時,我們已經滿足了所有的大小約束了,接下來讓我們設置位置。

*4.再一次,我需要為藍色視圖,定義一個指向父類視圖的約束。這非常簡單,關系僅僅是:

*保持它的底部與父類的底部距離為0

這個信息足夠定義了這個視圖的在垂直方向的位置了,因為父類的位置總是已經定義了。

所以我們如之前做的那樣,添加這個約束:ctrl + 點擊視圖,拖動到父類的底部,然后選擇“bottom space to bottom layout”(你可以在藍色視圖上釋放鼠標)。

注意:你也可以直接在文檔大綱中拖動,這種情況下,你可以看到所有可能的約束。

這時,我們所需要的所有的關系都可以滿足你的簡單界面的需要了。

例子3:代碼中更新約束


有些時候,為了更復雜的界面位置,我們需要控制更多的約束。而約束就是一個NSLayoutConstraint類的實例,我們顯然可以通過代碼,在運行時訪問約束相關的屬性。

轉到EXAMPLE_3 RESULT。你將會看到一個白色的標簽對齊於一個紅色視圖。如果你運行這個實例,你切換橫屏和豎屏時,這個紅色視圖會根據屏幕大小來改變它的高度。

讓我們看看怎么做到這個的!

*1.移動到EXAMPLE_3 START

*2.添加底部紅色視圖的約束

*設置與父類的Leading Space 和 Trailing Space,根據父類來定義寬度

*設置與父類底部的空間,使紅色視圖的底部固定在父類上。

*設置高度(記得嗎?ctrl + 點擊 ,垂直線軌跡)。

如果你完成了上面的步驟,結果因為像下面的一樣,有藍色約束線:

*3.填加下面的約束給UILabel

*水平居中標簽(Ctrl + 點擊標簽,水平拖動,釋放鼠標后選擇正確的約束)

*定義一個標簽與底部視圖的距離(Ctrl + 點擊標簽,拖動到底部的視圖然后放開,接着選擇“Vertical Spacing”)。

現在你應該也定義了UILabel所需要的約束了。

這時如果你運行這個例子,你將看到底部的視圖沒有在垂直方向上自動調整大小。確實,我們並沒有設置任何約束來讓它這樣,那么就讓我們設置吧。

*4.我已經把ResizerViewController類關聯到這個視圖控制器了。打開ResizeViewController.m,你將會看到第一個屬性:

*5.讓我們關聯這個Outlet到剛剛添加的高度約束。

所以再次打開Storyboard,從文檔大綱中,在EXAMPLE_3 START行上面 ctrl + 點擊,並拖動到高度約束,釋放鼠標,這樣就可以關聯起來了。

現在我們只需要更新這個約束的值就可以了。

*6.打開ResizerViewController.m 文件,並檢查這個函數:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
          if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
                self.CS_BottomView_Height.constant = 100;
          }else{
                self.CS_BottomView_Height.constant = 330;
          }
          [self.bottomView setNeedsUpdateConstraints];
}

這個函數里,我們僅僅根據設備的方向,來更新這個高度約束的常量屬性。

如果運行這個實例,你將看到想要的結果。

結尾


從我自身的直接經驗,我在本教程向你展示的就是你開始使用自動布局所需要的所有知識,當然,還有很多其他的自動布局功能值得研究,如“優先級”,自動布局的虛擬格式語言和NSLayoutConstraints的一些更高級的應用。我可能會在以后的帖子介紹它們。

一如往常,敬請期待並感謝您的閱讀。

[下載源碼][2]*
[2]: https://github.com/ariok/TB_AutoLayout "Think & Build"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM