iOS使用autolayout和sizeclass 解決適配問題(一)
剛接觸autolayout的時候我們不禁會問我為什么要使用autolayout 我使用frame 照樣可以寫項目為什么要用autolayout呢?
一。為啥使用autolayout?使用 autolayout 有什么好處?
隨著iPhone的種類不斷增多,不同尺寸、不同分辨率的iOS設備將會越來越多,使用傳統frame布局的工作量必將越來越大;加上蘋果發出的信號,使用autolayout勢在必行。
好了,那么autolayout了,它到底能解決什么問題,給我們帶來哪些好處?
1)你基本上可以不用考慮蘋果設備的各個屏幕不同分辨率的問題,你終于可以不用在viewDidLoad方法里判斷不同分辨率下,不同控件應該放在哪里,或者針對不同分辨率寫不同的storyboard和xib;
2)你可以拋棄那些根據不同文字來計算tableViewCell、UILabel高度的代碼了,因為autolayout會幫你自動計算好;
3)如果你的布局在橫屏豎屏下變化不是特別大,你不用再為橫著豎著寫兩套代碼或者寫兩個storyboard/xib了;
4)對于市面上的4.7寸和5.5寸iPhone或者其他尺寸的iPhone或者蘋果系列的設備,你基本上能很快甚至不用動一行代碼就完成他們的自適應屏幕布局,不用每次來了新分辨率,你只能say f*ck,然后改兩個通宵。
再看看蘋果的態度,默認就是選擇了使用autolayout。雖然我現在仍有時會罵autolayout,但我還是會堅決地選擇走上這條道路。
二。 autolayout 和sizeclass 兩者 有什么區別嗎?
首先說autolayout ,如果你選擇了autolayout 而沒有選擇sizeclass,那么你默認的所加的約束就是在iPhone或者ipad 上運行。具體操作見下圖:
xcode 在我們創建工程的時候已經默認的為我們選了 autolayout 和sizeclass ,由此可見蘋果是希望我們用兩者結合 來開發應用的。
我們不使用sizeclass 的時候 顯示的是這個樣子的:

那么使用了autolayout 和sizeclass 的是么狀態呢?

ok,我們可以看到上面就是采用了autolayout和sizeclass 之后的布局了。主要分為9種:寬(正常,任意, 緊湊),高(正常,任意, 緊湊)3x3共9種Size,每種Size都可以設置特定的一套布局,如果不特殊指定,默認是在(寬任意,高任意)模式下設置,且其他8種布局繼承它。因為Size Class在將屏幕分類后,執行布局的還是Autolayout。
假如iPad和iPhone的布局有差異,老式寫法是分成ipad.storyboard和iphone.storyboard來分別寫,這本身就是個bug,因為大部分控件其實并沒差別,新Size Class解決這個問題了沒?答案是肯定的,XIB中某個View的出現與否,約束的出現與否以及約束的值都是可以根據Size Class單獨設置的,也就是說現在一個storyboard是9合1的。比如有個Label,我只希望它出現在長寬緊縮的屏幕上時(腦補iwatch),這么勾選下就可以(出現或不出現被命名為”Installed”,這個選項可以從9個Size Class中多選。
通過下圖可以清楚的看到這九種不同的類型 對應 的設備。


如上圖可以看出我們installed 之后 ,我們的label 正常顯示 ,左邊視圖的層級中label顯示的是黑色。表示在當前選擇的any(任何設備) 上正常顯示。
當我們取消勾選installed 之后 會看到左邊視圖層級中label顯為灰色。 然后storybord 上面就不顯示了。其實這個顯示與否,只是說我們在特定的設備上顯示或者隱藏。

通過上面的例子也許你已經知道我們為什么要用sizeclass了。sizeclass的好處也是顯而易見的。
三。 我理解的autolayout
廢話不多說了,通過自己使用autolayout 總結自己理解的autolayout。僅僅是個人理解如有雷同,純屬巧合。
這里姑且把我們的手機或者模擬器比作一個豎直方向放置的的黑板,我們的控件就相當于放在黑板上的一件東西,它可以用繩子固定在上面。我所理解的加約束就是:有一個物體懸空放到黑板上與黑板接觸然后用繩子能固定住,繩子不能用多也不能用少。用得多了浪費并且還可能會產生沖突。用得少了,不能正確的固定位置然后還可能導致在你移動的時候可能會找不到位置(就是說這個物體在你的約束下不見了)。 說這么多還不如實戰。下面通過一些例子來說明約束的可操作性和便捷。
四。實踐
1.ok ,下面實現一個簡單的就是一個label 在屏幕在正中間。
我們需要加的約束是讓這個label 在x軸中心 在y軸中心。
約束見下圖

1).其中 Horizonetal Center in Controller 指的是“在水平方向居中 相對于它的父視圖。后面的數字表示是偏離中心多少。
2).下面的Vertical Center in Container 指的是 在豎直方向居中 同樣相對于父視圖。 后面的數字同樣表示是偏離中心多少。
我們在加完約束之后會發現出現了黃色的tips。這些黃色的tips 是怎么出現的呢。 看下圖:

1).其中 update Frame 表示的是我們根據約束來更新frame。
2). update constraints 就是我們根據當前的frame 來更新約束。
3).第三個reset to suggested constraints 表示是清空當前約束,然后重新設置成系統為我們建議的約束(這個約束不建議使用)
4).下面的apply to all views in container 表示的是 把所選約束或者frame的改變應用到容器中的所有view中。
這里選擇第一個 因為約束已經加好,只需要更新下frame就好。
補充說明一下:為什么要更新frame:因為我們在拖控件的時候不可能一下子就拖到我們想要的位置。這就需要我們先加好約束,然后根據約束來更新frame。
我們使用了sizeclass 那我們來看下效果。 在iPhone 和ipad 上的效果
右邊是6p


下面是ipad

通過上面三個圖 我們可以看出我們使用一套界面就可以對iphone ipad 進行適配。要做真正的適配這些是還不夠的還需要圖片的配置。因為不同設備下對圖片對分辨率的要求是不一樣的。
2。第二彈
這個例子實現的效果:兩個視圖 等高等寬間距固定(80)。并且視圖距離上邊界30 距離左邊界/右邊界 20.
下面看下效果圖:
旋轉后


遇到這樣一個需求我們應該怎么做呢?當然不能盲目來寫。要想好采取什么樣的約束。首先距離上邊界和距離左右邊界的約束不難,等寬等高這個約束要考慮到。不能固定寬和高的大小,如果固定了根據當前的需求不能滿足兩者的距離是80.如果不固定寬高的話,那么我們得到視圖的寬高就是固定的。還有就是相對位置的問題,A固定以后,B加的約束跟A有關那么B加的約束就是相對約束。就拿藍色view 和紅色view 來說吧,要想實現兩者在同一水平線上 其中紅色view 距離父視圖頂部30是固定的。我們有兩種方案1.我們可以直接設置藍色view距離父視圖也是30.這樣同樣可以解決問題。2.由于紅色視圖是固定的,藍色view 的TOP和 紅色view 的TOP在同一水平線上也能實現效果。
兩種方案都可以實現效果,那么我們應該怎么選擇呢?首先我們要從代碼維護成本來說,在兩者都能完成目的的情況下,低成本的應用維護才是目的。我們采用方案一的話如果我們想修改距離上邊界的約束。那么我們就需要修改紅色和藍色view 的約束。我們需要修改的約束有兩個。采用方案二的話我們只需要修改紅色view 距離上邊界的距離就好。因為藍色view 是相對于紅色view來設置約束的。這樣維護的成本會降低。
具體操作可查看demo 地址 :https://github.com/shaveKevin/AutolayoutAndSizeclassPartOne.git
下面就加的約束來進行解釋.

標注⑦表示的是 這是紅色view 下面的約束對應的也是紅色view 的約束。
① .約束一 表示的是 紅色想第一自己 的寬高比是1:1 因為這里需要的是狂傲相同。當讓這個可以根據不同的需求來設置不同的寬高比。
②.約束二表示的是藍色和紅色的TOP 也就是頂部在一條水平線上。寫這個約束的時候,首先把紅色的確定,然后讓藍色相對紅色來加約束。(也就是說這個約束是加在藍色view上的 因為約束是相對的,比如說我的位置是固定的,假設兩人面對面間距5m,也就是說你在我正前方5m,那么我再你正前方也是5m ),使用的多了,也就明白約束的相對性.
③.約束三表示的是 藍色view相對紅色view 寬度是相等的。
④。約束四 表示的是紅色view距離父視圖左側的距離是20.
⑤。約束五 表示的是紅色視圖右邊界與藍色視圖的左邊界的距離是80 就是說兩個視圖間距80.
⑥。約束六 表示的是紅色視圖的頂部相對于父視圖來說距離是30
下圖的標注的是藍色view 的約束。

①。約束一表示的是藍色view 相對自己的寬高比是1:1
②。約束二表示的是藍色view 和紅色view頂部保持在同一水平線上
③。約束三表示的是藍色view相對紅色view 寬度是相等的。
④。約束四表示的是藍色view距離父視圖右邊界距離是20
⑤。約束五表示的是藍色view 的左邊界距離紅色view 的右邊界距離是80 。
上面的描述純屬個人理解,如果描述的不對,請指出。
(例子不斷增加中。。。)
五。總結。
//未完待續。。。
六 參考博客
http://segmentfault.com/a/1190000000646452從此愛上iOS Autolayout
http://blog.sunnyxx.com/2014/09/09/ios8-size-classes/iOS8 Size Classes初探
七 demo 地址
iOS開發交流群:214541576