AutoLayout自動布局

2022-09-16 03:39:13 字數 4426 閱讀 6555

autolayout(自動布局)入門

這是博主的wwdc2012筆記系列中的一篇,完整的筆記列表可以參看這裡。如果您是首次來到本站,也許您會有興趣通過rss,或者通過頁面左側的郵件訂閱的方式訂閱本站。

autolayout是一種基於約束的,描述性的布局系統。 auto layout is a constraint-based, descriptive layout system.

總而言之,autolayout為開發者提供了一種不同於傳統對於ui元素位置指定的布局方法。以前,不論是在ib裡拖放,還是在**中寫,每個uiview都會有自己的frame屬性,來定義其在當前檢視中的位置和尺寸。使用autolayout的話,就變為了使用約束條件來定義view的位置和尺寸。這樣的最大好處是一舉解決了不同解析度和螢幕尺寸下view的適配問題,另外也簡化了旋轉時view的位置的定義,原來在底部之上10畫素居中的view,不論在旋轉螢幕或是更換裝置(ipad或者iphone5或者以後可能出現的mini ipad)的時候,始終還在底部之上10畫素居中的位置,不會發生變化。

總結

使用約束條件來描述布局,view的frame會依據這些約束來進行計算 describe the layout with constraints, and frames are calculated automatically.

總結

autoresizing mask是autolayout的子集,任何可以用autoresizing mask完成的工作都可以用autolayout完成。autolayout還具備一些autoresizing mask不具備的優良特性,以幫助我們更方便地構建介面。

最簡單的使用方法是在ib中直接拖。在ib中任意乙個view的file inspector下面,都有use autolayout的選擇框(沒有的同學可以考慮公升級一下xcode了=。=),鉤上,然後按照平常那樣拖控制項就可以了。拖動控制項後在左邊的view hierarchy欄中會出現constraints一向,其中就是所有的約束條件。

選中某個約束條件後,在右邊的attributes inspector中可以更改約束的條件,距離值和優先度等:

對於沒有自動新增的約束,可以在ib中手動新增。選擇需要新增約束的view,點選選單的edit->pin裡的需要的選項,或者是點選ib主檢視右下角的

按鈕,即可新增格外的約束條件。

視覺化的新增不僅很方便直觀,而且基本不會出錯,是優先推薦的新增約束的方式。但是有時候只靠ib是無法完成某些約束的新增的(比如跨view hierarchy的約束),有時候ib新增的約束不能滿足要求,這時就需要使用約束的api進行補充。

建立ios6中新加入了乙個類:nslayoutconstraint,乙個形如這樣的約束

對應的**為

[nslayoutconstraint constraintwithitem:button

attribute:nslayoutattributebottom

relatedby:nslayoutrelationequal

toitem:superview

attribute:nslayoutattributebottom

multiplier:1.0

constant:-padding]

這對應的約束是「button的底部(y) = superview的底部 -10」。

新增在建立約束之後,需要將其新增到作用的view上。uiview(當然nsview也一樣)加入了乙個新的例項方法:

* 對於兩個不同層級view之間的約束關係,新增到他們最近的共同父view上

* 對於有層次關係的兩個view之間的約束關係,新增到層次較高的父view上

重新整理可以通過-setneedsupdateconstraints和-layoutifneeded兩個方法來重新整理約束的改變,使uiview重新布局。這和coregraphic的-setneedsdisplay一套東西是一樣的~

uikit團隊這次相當有愛,估計他們自己也覺得新加約束的api名字太長了,因此他們發明了一種新的方式來描述約束條件,十分有趣。這種語言是對視覺描述的一種抽象,大概過程看起來是這樣的:

accept按鈕在cancel按鈕右側預設間距處

最後使用vfl(visual format language)描述變成這樣:

[nslayoutconstraint constraintswithvisualformat:@"[cancelbutton]-[acceptbutton]" 

options:0

metrics:nil

views:viewsdictionary];

其中viewsdictionary是繫結了view的名字和物件的字典,對於這個例子可以用以下方法得到對應的字典:

uibutton *cancelbutton = ...  

uibutton *acceptbutton = ...

viewsdictionary = nsdictionaryofvariablebindings(cancelbutton,acceptbutton);

生成的字典為

當然,不嫌累的話自己手寫也未嘗不可。現在字典啊陣列啊寫法相對簡化了很多了,因此也不複雜。關於objective-c的新語法,可以參考我之前的一篇wwdc 2012筆記:wwdc 2012 session筆記——405 modern objective-c。

[wideview(>=60@700)]

v:[redbox][yellowbox(==redbox)]

h:|-[find]-[findnext]-[findfield(>=20)]-|

因為涉及約束問題,因此約束模型下的所有可能出現的問題這裡都會出現,具體來說包括兩種:

布局不能確定指的是給出的約束條件無法唯一確定一種布局,也即約束條件不足,無法得到唯一的布局結果。這種情況一般新增一些必要的約束或者調整優先順序可以解決。無法滿足約束的問題**是有約束條件互相衝突,因此無法同時滿足,需要刪掉一些約束。兩種錯誤在出現時均會導致布局的不穩定和錯誤,ambiguous可以被容忍並且選擇一種可行布局呈現在ui上,unsatisfiable的話會無法得到ui布局並報錯。

對於不能確定的布局,可以通過除錯時暫停程式,在debugger中輸入

來檢查是否存在ambiguous layout以及存在的位置,來幫助新增條件。另外還有一些檢查方法,來檢視view的約束和約束狀態:

2023年9月1日作者更新:在ios7和xcode5中,ib在新增和檢查autolayout約束方面有了長足的進步。現在使用ib可以比較容易地完成複雜約束,而得益於新的ib的約束檢查機制,我們也很少再會遇到遺漏或者多餘約束情況的出現(有問題的約束條件將直接在ib中得到錯誤或者警告)。但是對於確實很奇葩的約束條件有可能使用ib無法達成,這時候還是有可能需要**補充的。

動畫是ui體驗的重要部分,更改布局以後的動畫也非常關鍵。說到動畫,core animation又立功了..自從ca出現以後,所有的動畫效果都非常cheap,在auto layout中情況也和collection view裡一樣,很簡單(可以參考wwdc 2012 session筆記——219 advanced collection views and building custom layouts),只需要把layoutifneeded放到animation block中即可~

[uiview animatewithduration:0.5 animations:^];

自動布局 Autolayout

簡介 在以前的ios程式中,是如何設定布局ui介面的?經常編寫大量的座標計算 為了保證在3.5 inch和4.0 inch螢幕上都能有完美的ui介面效果,有時還需要分別為2種螢幕編寫不同的座標計算 即傳說中的 螢幕適配 什麼是autolayout?autolayout是一種 自動布局 技術,專門用來...

Autolayout自動布局3

不要將autoresizingmask轉為autolayout的約束 blueview.translatesautoresizingmaskintoconstraints no uiview redview uiview alloc init self.view addsubview redview...

iOS 自動布局Autolayout

自動布局 autolayout 簡介 在以前的ios程式中,是如何設定布局ui介面的?經常編寫大量的座標計算 為了保證在3.5 inch和4.0 inch螢幕上都能有完美的ui介面效果,有時還需要分別為2種螢幕編寫不同的座標計算 即傳說中的 螢幕適配 什麼是autolayout?autolayout...