整理轉(zhuǎn)載自:Tommy@迷糊小書童和www.cnblogs.com
前言
iOS8和iPhone6發(fā)布已經(jīng)過去蠻久了,廣大的果粉終于迎來了大屏iPhone,再也不用糾結(jié)為大屏買三星舍蘋果了…但是對于iOS開發(fā)人員來說,迎來了和Android開發(fā)開發(fā)一樣的問題—>各種屏幕的適配(是不是可以要求加工資的節(jié)奏).對于適配,網(wǎng)傳各種有關(guān)Size Class的論點,前段時間太忙,一直沒去研究,套用+總的話,蘋果在適配方面提供的方法做的比安卓好太多了.自己實測之后,確實很方便0.0(不過,還是想說,適配的核心始終是AutoLayout)
概念初探
iOS8之前,公司在開發(fā)項目時,先做的iPhone版,然后要求開發(fā)iPad版本,其實內(nèi)容是完全一樣的,只是UI變化了,但是我們就需要建立2個工程來分別對應(yīng)實現(xiàn).iOS8推出的Size Class,可以讓我們在一個工程的storyboard中進行所有尺寸屏幕的適配,不僅是iPhone 4s-5/5s-6-6 Plus,還包括iPad界面.它引入了一種新的概念,拋棄傳統(tǒng)意義上我們適配時所謂的具體寬高尺寸,把屏幕的寬和高分別分成兩種情況:Compact-緊湊, Regular-正常(Any-任意,其實就是這2種的組合,所以我沒分成3種情況).搭配起來是3*3,也就是無論如何變化,加起來也就9種,如上圖.
1.實際應(yīng)用中,這Compact,Any,Regular如何運用呢?**
w:Any h:Any 是我們剛建立工程時候默認選擇的,算是一切描述的父類.其他的種類描述都是在此基礎(chǔ)上變化的,比如:如果weight設(shè)為Any,height設(shè)置為Regular,那么在該狀態(tài)下的界面元素在只要height為Regular,無論weight是Regular還是Compact的狀態(tài)中都會存在.于是:
w:Compact h:Compact - (w:Any h:Compact , w:Compact h:Any , w:Any h:Any)
w:Regular h:Compact - (w:Any h:Compact , w:Regular h:Any , w:Any h:Any)
w:Compact h:Regular - (w:Any h:Regular , w:Compact h:Any , w:Any h:Any)
w:Regular h:Regular - (w:Any h:Regular , w:Regular h:Any , w:Any h:Any)
2. 再來看一組數(shù)據(jù)和一張圖(國外一位博主給出的,很形象):
iPhone4S,iPhone5/5s,iPhone6
豎屏:(w:Compact h:Regular)
橫屏:(w:Compact h:Compact)
iPhone6 Plus
豎屏:(w:Compact h:Regular)
橫屏:(w:Regular h:Compact)
iPad
豎屏:(w:Regular h:Regular)
橫屏:(w:Regular h:Regular)
3.可以總結(jié)為:
如果項目不支持橫屏顯示,使用w:Compact h:Regular(或者直接取消使用Size Class)
如果項目支持橫屏顯示,使用w:Compact h:Regular+w:Any h:Compact
對于一些公有的約束(任意組合中都適用),一般放在w:Any h:Any中設(shè)置
iPad同理
所以,我覺得Size Classes最大的幫助是,解決橫屏適配和iPhone iPad共享一個設(shè)計板…(個人意見)
試驗反饋一
-
1.首先,先建立一個工程,展開如下頁面
1418795619564332.png
PS:這是iOS8的新特性,真的用到項目里需要等放棄兼容iOS7 。。。顯然,目前還是不行的
-
2.在Any Any情況下,放置一個Label,并設(shè)置約束上-左-下-右為0-0-20-0
1418795649852495.png
1418795676961340.png -
3.在Compact Any情況下,又放置一個Label,并設(shè)置約束上為20
1418795705149952.png -
4.繼續(xù)在Compact Any情況下,來看看橫屏狀態(tài)下的變化
1418795785522114.png -
5.最后切換到Regular Any下,完成6 Plus 的橫屏顯示
1418795810496572.png
試驗反饋二
試驗一里面,驗證了一下概念中所列舉的各個屏幕適用的組合,接下來,算是Size Classes 解決橫屏的妙用
PS:運用于,橫屏適配,重新排版豎屏時候的UI布局
除了改動不同組合下約束,也能改動控件在不同組合下是否顯示
試驗反饋三
AutoLayout這里不給具體如何設(shè)置,因為不知道如何寫,感覺還是大家多動手去寫,去試,最有效了
下面給出AutoLayout設(shè)置的圖解
簡答測試Demo結(jié)果圖:
如果不橫屏,也可以直接取消Size Classes(圖不一樣,不同時間寫的…囧)
4.Size Classes手寫代碼
為了表征Size Classes
,Apple在iOS8中引入了一個新的類,UITraitCollection。這個類封裝了像水平和豎直方向的Size Class等信息。iOS8的UIKit中大多數(shù)UI的基礎(chǔ)類(包括UIScreen,UIWindow,UIViewController和UIView)都實現(xiàn)了UITraitEnvironment這個接口,通過其中的traitCollection這個屬性,我們可以拿到對應(yīng)的UITraitCollection
對象,從而得知當前的Size Class,并進一步確定界面的布局。和UIKit中的響應(yīng)者鏈正好相反,traitCollection
將會在view hierarchy中自上而下地進行傳遞。對于沒有指定traitCollection的UI部件,將使用其父節(jié)點的traitCollection。這在布局包含childViewController的界面的時候會相當有用。在UITraitEnvironment這個接口中另一個非常有用的是-traitCollectionDidChange:。在traitCollection發(fā)生變化時,這個方法將被調(diào)用。在實際操作時,我們往往會在ViewController中重寫-traitCollectionDidChange:或者-willTransitionToTraitCollection:withTransitionCoordinator:方法(對于ViewController來說的話,后者也許是更好的選擇,因為提供了轉(zhuǎn)場上下文方便進行動畫;但是對于普通的View來說就只有前面一個方法了),然后在其中對當前的traitCollection進行判斷,并進行重新布局以及動畫。代碼看起來大概會是這個樣子:
- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection
withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
{
[super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:^(id <UIViewControllerTransitionCoordinatorContext> context)
{
if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
//To Do: modify something for compact vertical size
} else {
//To Do: modify something for other vertical size
}
[self.view setNeedsLayout];
} completion:nil];
}
在兩個To Do處,我們要手寫代碼針對不同的狀態(tài)做調(diào)整。