天天看點

從此愛上iOS Autolayout

從此愛上iOS Autolayout

這篇不是autolayout教程,隻是autolayout動員文章和經驗之談,在本文第五節友情連結和推薦中,我将附上足夠大家熟練使用autolayout的教程。這篇文章兩個月前就想寫下來,但因為一直工作較多,沒有時間來完成。今天終于狠下心,丢下代碼不寫,來完成他吧!

一、别和我提Autolayout,我想死!!

從iOS6/​​xcode​​4開始,蘋果開始提供了autolayout——一種對不同螢幕尺寸有更好相容的自動布局機制,但我相信大多數人在剛接觸autolayout時,一定和我一樣,幾乎快被其折磨緻死!

autolayout因為布局思路與傳統frame有所不同,國内關于autolayout的​​教程​​有過少,且autolayout在剛上手時靈活性不易掌控,導緻大家更多選擇了放棄。

二、為啥我要用autolayout?

随着3.5寸/4寸iPhone在市面同時使用越來越多,以及即将上市的iPhone6、iPhone6L,不同尺寸、不同分辨率的iOS裝置将會越來越多,使用傳統frame布局的工作量必将越來越大;加上​​蘋果​​發出的信号,使用autolayout勢在必行。

好了,我該來表揚表揚autolayout了,它到底能解決什麼問題,給我們帶來哪些好處?

1)你基本上可以不用考慮3.5寸和4寸以及即将上市的x.x寸螢幕不同分辨率的問題,你終于可以不用在viewDidLoad方法裡判斷不同分辨率下,不同控件應該放在哪裡,或者針對不同分辨率寫不同的storyboard和xib;

2)你可以抛棄那些根據不同文字來計算tableViewCell、UILabel高度的代碼了,因為autolayout會幫你自動計算好;

3)如果你的布局在橫屏豎屏下變化不是特别大,你不用再為橫着豎着寫兩套代碼或者寫兩個storyboard/xib了;

再看看​​蘋果​​的态度,預設就是選擇了使用autolayout。雖然我現在仍有時會罵autolayout,但我仍然會堅決地選擇走上這條道路。

三、Autolayout之折騰二三事

剛剛表揚完autolayout,那我得為和我一樣,願意選擇走上這條道的同志們提點醒了,你究竟要做好哪些折騰的準備。

3.1.布局思維的轉變

傳統布局思路中,一個view在哪裡有多大,那就寫清楚它的坐标位置和寬高就定了,平時用CGRect和CGPoint這兩種模型就足夠了,而且它一定非常聽你的話,寫的是多少,它絕對就是多少;但是autolayout的思路卻變化了,或者說改進了,它囊括了傳統frame布局思路,除了可以告訴view的坐标和寬高,它更提供了一種相對的概念,比如:

1)view相對于螢幕視圖左邊5點,右邊10點,上面15點,下面20點,如果螢幕的長寬比例發生了改變(比如從3.5寸的320:480變成了4寸的320:568,或者從橫屏切換到了豎屏),view仍然會随着螢幕的比例而拉伸改變,仍然保持離螢幕視圖左邊5點,右邊10點,上面15點,下面20點;

2)view1和view2之間相距10點,當螢幕尺寸發生改變或者旋轉時,他倆仍然可以通過改變自身的尺寸或位置改變來保證它們中間就是相距10點;

3)...

是以,使用autolayout的第一步是你需要考慮它相對于superView或者brotherView的上下左右的距離,改變自己布局的思維。

3.2.使用autolayout可能會經常得到自己不想看到的樣子,而且你改變frame還沒用

frame時代,是你寫的多少位置點就是多少位置點,view不會被自動的拉伸或者改變位置,但是autolayout中的view卻會根據螢幕長寬比或者其他view的改變而改變,你經常就會看到被自動布局成了不是你想的樣子,這也是太多人被折磨的原因。隻要你考慮的相對的位置不正确,它真的就可能會亂掉。

3.3.autolayout的VFL(Visual Format Language)文法初看起來真蛋疼

好吧,既然使用了autolayout,使用frame來改變位置不起作用了,那我也用代碼來完成autolayout總行了吧。但是,讓我選一段最普通的VFL代碼給你看看:

NSString *vfl = @"V:|-5-[_view]-10-[_imageView(20)]-10-[_backBtn]-5-|";      

納尼?!這是什麼地幹活?!我又要付出學習成本了啊!!!其實這段話就是說,在垂直方向從上到下,view離父視圖5點,imageView距離view 10點,同時imageView是20點高,backBtn離imageView底部10點,距離父視圖底部5點。

3.4.手動Constraint書寫,那個長長長啊~~

當然,你還可以一個一個的寫布局限制Constraint,就和frame分别指定origin和size類似,但是卻像這樣:

[self.view addConstraint: [NSLayoutConstraint constraintWithItem:blueViewattribute:NSLayoutAttributeLeftrelatedBy:NSLayoutRelationEqualtoItem:redViewattribute:NSLayoutAttributeLeftmultiplier:1constant:0]];      

而上文中的“view離父視圖5點,imageView距離view 10點,同時imageView是20點高,backBtn離imageView底部10點,距離父視圖底部5點”每一個逗号短句都是像這樣的一個constraint。

四、你是不是已經準備放棄了?NO!說好的愛上Autolayout呢!

寫到這裡,我忽然覺得我是在黑autolayout了,不,看我的題目,我是真的已經愛上使用autolayout了。就讓我來說說應該怎麼使用autolayout。

4.1.autolayout一般應用步驟和最适宜場景

當你的頁面不會變更整體布局和​​設計​​​,隻有在不同螢幕尺寸、不同文字和内容下有适應性的變化,那這種情況使用autolayout就再适宜不過了。不會在像frame的時代,苦逼的要為不同螢幕尺寸計算各自的位置點坐标和大小了。通常使用​​xcode​​​->Editor->Pin/Align菜單為視圖添加限制即可。一般通過InterfaceBuilder确定控件位置,當存在需要自動被拉伸、适應或位移的控件時就要添加constraint;具體使用​​教程​​可參考《開始iOS 7中自動布局教程1》

4.2.你的視圖有比較簡單的布局改變

當需要産生動畫或動态添加視圖時,autolayout就暴露了出我認為讓人抓狂的元兇——優先級(Priority)和布局沖突。autolayout對于相同方位的限制,如都是描述離superview上邊緣距離的限制,如果這兩個限制的數值不同,但是優先級一樣,則autolayout将報布局沖突,将會根據其計算丢棄某一條限制(這時可能就會丢棄你想要的限制,而恰恰保留了你不想看到的布局)。是以,當我們發生布局變化時,無法像frame的絕對定位,直接改變,并且隻有唯一的位置資訊。那麼,我們該怎麼處理這種布局沖突呢?那就是讓描述相同但數值不同的這兩個限制采用不同的優先級。autolayout預設将使用數值較大的優先級限制。

但是當我們新增了一個更高優先級限制改變了視圖布局,在完成一些操作後,又想變回去怎麼辦?這時就必須删除更高優先級的限制。

是以,對于視圖有動态變更時,我的通常做法是:為需要變更的控件新增預設constraint,但對于這個預設constraint先降低優先級,在發生變化時再新增一個更高優先級的constraint2,且代碼中用一個Dictionary緩存該constraint2的對象,便于我随時删除或重新新增,讓視圖來回變化。

4.3.你的視圖有較為複雜的動畫效果或者較大的布局改變

雖然autolayout可以完成所有的布局問題,但它仍然在某些情況下是不友善的,就像4.2節描述的,每次改變你必須新增或删除一個不同優先級的constraint,單說構造constraint對象的工作就夠嗆了,還可能必須緩存該對象,便于之後清除。是以,當你需要非常頻繁的變更控件布局,并且變更的位置是不确定的(例如通過手勢拖動一個視圖到螢幕任意位置),那麼,我建議此視圖不要使用autolayout,而使用frame的所寫即所得的絕對定位方式更好,你隻需要充分考慮各種螢幕适配,并為其計算适合的坐标點即可。同時,我還建議這種頻繁變更的視圖甚至不要InterfaceBuilder來繪制,最好直接代碼​​書寫​​,因為一旦你勾選了autolayout,那麼storyboard中的所有視圖都将autolayout。而當你需要變更視圖布局時,則必須使用

​view.translatesAutoresizingMaskIntoConstraints = NO;​

​​

​superview.translatesAutoresizingMaskIntoConstraints = NO;​

來避免為你的視圖新增預設autolayout限制。

五、友情連結和推薦

1.《開始iOS 7中自動布局教程1》

這個​​教程​​看完基本上可以比較熟悉的使用autolayout,再結合本文的一些經驗,應該能夠解決大部分問題了。而該文的教程2沒有中文翻譯,隻有英文原版:《Beginning Auto Layout Tutorial in iOS 7: Part 2》

2.《Autolayout及VFL經驗分享》

這篇文章以較簡單的描述囊括了VFL使用方法和常用的autolayout技巧。足夠大家使用了。

3.《AutoLayout(自動布局)入門》