iOS自動佈局(Auto Layout

轉載地址:http://www.bingfengsa.com/info/31492.html

學會愛上iOS自動佈局(Auto Layout) - 劍尖

本文翻譯自Yari Dareglia的LEARN TO LOVE AUTO LAYOUT文章先生們,女士們,讓我們以正確的心態開始本教程吧:自動佈局就是簡單!我花了一段時間來掌握自動佈局是如何工作的,現在回頭看,我發現我絕對是高估了這個問題。在這篇文章中我將介紹一些基本的方面和一些技巧,我敢肯定會幫助你在面對自動佈局時不在害怕。Xcode4在Xcode5之前,自動佈局可能是你在你的應用中實現的最討厭的“功能”。標記“使用自動佈局”就像說“把我變瘋吧”。這就是爲什麼我從來沒有對這個標記打勾。爲自本文翻譯自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在垂直和水平方向始終處於中心位置,而不管屏幕的大小的旋轉方向。

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

把眼光移到 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:固定內容大小


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

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

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

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

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

類似按鈕和標籤這些對象,是根據他們的內容來決定大小的。一個特定的方法


會返回這類視圖的大小信息,所以你不需要通過約束來覆蓋這些信息。

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

例子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的一些更高級的應用。我可能會在以後的帖子介紹它們。

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

下載源碼*

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章