螢幕適配 size class
1. 三種尺寸類型(size class)
如果把螢幕的長和寬都按長度劃分三種類型(官網中成為size class):壓縮(compact)、任意(any)、常規(regular),那麼長和寬的組合就有9種類型。這裡我把每一種類型稱為一種模式。
另外,螢幕的狀態根據尺寸大小和其方向可以分為很多情況。模式和螢幕的狀態有著對應關係,可以是一對一,也可以是一對多。比如說,一種模式叫任意模式,也就是長是任意的,寬也是任意的,這種模式可以對應所有的螢幕狀態。
可以為同一介面定義其在不同模式下的布局。當app運行時會檢測裝置的螢幕狀態(螢幕尺寸以及螢幕方向),以此來決定使用哪種模式下的布局。
在“任意模式”下添加的控制項和約束是在所有模式下都生效的。
在某一模式下添加的控制項和約束,是該模式私人的。
最高效率的做法是使任意模式下的布局,適配所有螢幕狀態。但是有時候,由於展示的內容的限制,不同尺寸、或者橫、豎屏的布局會有比較大的區別,有時甚至會增減控制項。此時就要分開不同模式來布局使用者介面。
2. 模式的切換
模式的切換是通過中的size class工具來實現的。框選不同數目的格子對應不同的模式,在工具下方的文字表明了該模式適用於什麼螢幕狀態(螢幕尺寸、橫屏還是豎屏)。注意,格子的數目是有含義的,水平方向上格子數目表示寬的尺寸類型,垂直方向上的格子數目表示高的尺寸類型。三個尺寸類型compact、any、regular對應的格子數分別是1個、2個、3個。
vcHLoaPOqsHLsry+1rXEyrG68r+0tcPK5rf+o6y/ydLUvavEo8Tixve1xLPftOe6zbe9z/Kx5NK7z8KjrM2ouf3Pws28wb249tGhz+7AtLjEseSho9ei0uLEo8Tixve1xLPftOe6zbe9z/K6zbWxx7C1xLK8vtbEo8q9ysfDu9PQudjPtbXEoaM8L3A+DQo8cD48aW1nIGFsdD0="這裡寫圖片描述" src="http://www.bkjia.com/uploads/allimg/160423/0420214459-1.png" title="\" />
上面說到的螢幕狀態與寬、高的尺寸類型的對應關係,這裡有表格可以參考(來自蘋果官網):
3. 不同模式下視圖的顯示
上面說到,需要分開不同模式來布局的一種情況是,橫豎屏的區別很大,甚至會增減視圖。此時,視圖可能在某種模式下需要顯示,在某種模式下不顯示。設定視圖是否在某種情況下顯示的方法如(需要先點擊一下要設定的視圖)。勾選Installed就表明在“任意模式”顯示該視圖,或者點擊“+”號,選擇一種模式,再通過是否勾選Installed決定視圖在該模式下是否顯示。
4. 不同模式片的顯示
為了適應不同的模式,同一張圖片可能需要多個尺寸的版本。這種情況下,適應Assets.xcassets來管理這些圖片。建立一個Image Set。在這個Image Set中右側,可以選擇需要支援的裝置:
還可以通過選擇Width和Height,組合出不同的模式,然後按實際情況來給某些模式提供對應的圖片版本。將對應的圖片,填入對應的模式中。展示了包含了若干模式的一個Image Set,圖中指明了其中的標識的含義:
5. 使用者觸發螢幕狀態的變化
上面多次提到螢幕狀態,包括螢幕尺寸、螢幕方向。這些資訊封裝成了一個類——UITraitCollection。
使用者改變螢幕狀態以後(橫屏、豎屏等動作),發生以下動作:
(1)當螢幕狀態變化快要改變的時候UIKit會調用這個方法來通知各個相關的視圖控制器
willTransitionToTraitCollection:withTransitionCoordinator:
(2)當視圖控制器的尺寸快要變化的時候,UIKit會調用
viewWillTransitionToSize:withTransitionCoordinator:
(3)當螢幕狀態發生變化以後,UIKit會調用
traitCollectionDidChange:
父控制器可以固定其子視圖控制器的模式,讓它不受螢幕狀態的變化影響。有兩個方法可以實現(iOS 8.0 and later):
-(void)setOverrideTraitCollection:(UITraitCollection *)collection? forChildViewController:(UIViewController *)childViewController`
-(UITraitCollection *)overrideTraitCollectionForChildViewController:(UIViewController *)childViewController