一個自適應(yīng)界面應(yīng)該響應(yīng)trait和size變化淑际。在視圖控制器基本脸侥,使用trait大體上決定你所展示的內(nèi)容和內(nèi)容的布局建邓。例如,當(dāng)size類改變睁枕,你會選擇改變視圖屬性官边,顯示或隱藏視圖,或者顯示一組完全不同的視圖外遇。在做出這些重大決策注簿,使用size變化來調(diào)整你的內(nèi)容。
自適應(yīng)trait變化
trait提供一種方式跳仿,可以針對不同的環(huán)境以不同的方式配置app诡渴,可以使用它們來粗略的調(diào)整界面。大部分情況下菲语,可以直接在storyboard文件中修改trait妄辩,但是有些需要額外的代碼。
配置storyboard處理不同size類
界面構(gòu)建器使界面自適應(yīng)不同size類變得更容易山上。storyboard編輯器支持配置不同的size類顯示界面眼耀,刪除視圖的具體配置,指定不同布局約束佩憾。還可以創(chuàng)建圖像asset為不同size類提供不同圖像哮伟。使用這些工具意味著不需要在運行時以編程的方式改變。相反妄帘,當(dāng)當(dāng)前size類改變楞黄,UIKit自動更新界面。
圖13-1展示了在界面構(gòu)建器中用于配置界面的工具寄摆。size類查看控制改變界面視圖的外觀谅辣。使用該控制可以查看給定一個size類的界面外觀。對于個人視圖婶恼,使用安裝控制來配置該視圖是否存在給定size類配置桑阶。使用復(fù)選框左邊的加號(+)按鈕添加新的配置柏副。
注意:未卸載的視圖仍然在視圖層級結(jié)構(gòu)中,可以正常操作蚣录,但他們不會出現(xiàn)在屏幕上割择。
圖片asset是存儲應(yīng)用圖片資源的首選方法。每個圖片asset包含相同圖片的多個版本萎河,每個版本用于特定配置荔泳。除了為標(biāo)準(zhǔn)和Retina顯示指定不同的圖片,還可以為不同水平和垂直size類指定不同圖片虐杯。當(dāng)配置了圖片asset玛歌,UIImageView對象自動根據(jù)當(dāng)前size類和分辨率選擇圖片。
圖13-2 展示了圖片asset屬性擎椰。改變寬度和高度屬性會在圖片目錄中添加slot支子,為每個size類對應(yīng)的slot添加圖片。
改變子視圖控制器的trait
子視圖控制器默認繼承他們父視圖控制器的trait达舒。如size類值朋,使每個子視圖控制器與父視圖控制器有相同的trait沒有意義。例如巩搏,在普通環(huán)境中的視圖控制器可能希望給一個或多個子視圖分配一個緊湊的size類昨登,減少子視圖的空間。當(dāng)實現(xiàn)一個容器視圖控制器贯底,通過調(diào)用容器視圖控制器的setOverrideTraitCollection:forChildViewController:方法修改子視圖的trait丰辣。
列表13-1展示了如何創(chuàng)建一組新的trait,并將其關(guān)聯(lián)到子視圖控制器丈甸。只需在父視圖控制器中執(zhí)行一次該代碼糯俗。覆蓋子視圖的trait直到再次改變trait或者從視圖控制器層級結(jié)構(gòu)中刪除trait。
列表13-1 改變子視圖控制器的trait
<pre><code>
UITraitCollection* horizTrait = [UITraitCollection
traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
UITraitCollection* vertTrait = [UITraitCollection
traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];
UITraitCollection* childTraits = [UITraitCollection
traitCollectionWithTraitsFromCollections:@[horizTrait, vertTrait]];
[self setOverrideTraitCollection:childTraits
forChildViewController:self.childViewControllers[0]];
</pre></code>
當(dāng)改變父視圖控制器的trait睦擂,子視圖繼承任何沒有顯式覆蓋父類的trait。例如杖玲,當(dāng)父視圖控制器的水平size類從常規(guī)變成緊湊顿仇,在前面例子中的視圖控制器保持其常規(guī)水平size類。然而摆马,如果displayScale trait改變臼闻,子視圖繼承新值。
presented視圖控制器自適應(yīng)新樣式
presented視圖控制器在水平常規(guī)和緊湊環(huán)境中自適應(yīng)囤采。當(dāng)從水平常規(guī)環(huán)境過渡到水平緊湊環(huán)境時述呐,UIKit默認改變內(nèi)置present風(fēng)格為 UIModalPresentationFullScreen。對于自定義present風(fēng)格蕉毯,present控制器可以決定適應(yīng)行為并根據(jù)情況調(diào)整乓搬。
對于一些app思犁,采用全屏風(fēng)格可能存在問題。例如进肯,通常點擊其他區(qū)域激蹲,彈窗dismiss,但在緊湊環(huán)境中不可能這樣做江掩,彈窗覆蓋整個屏幕学辱,如圖13-3所示。當(dāng)默認自適應(yīng)風(fēng)格不合適环形,可以告訴UIKit使用不同的風(fēng)格或者present一個完全不同視圖控制器策泣,使之更適合全屏風(fēng)格。
要改變present風(fēng)格的默認自適應(yīng)行為抬吟,分配 delegate 到相關(guān)present控制器萨咕。使用presented視圖控制器的 presentationController 屬性訪問presentation控制器。presentation控制器在做出自適應(yīng)相關(guān)更改前查詢代理對象拗军。代理可以返回不同Presentation風(fēng)格任洞,而不是默認的。代理可以提供Presentation控制器另一個要顯示的視圖控制器发侵。
使用代理的adaptivePresentationStyleForPresentationController: 方法指定不同presentation風(fēng)格而不是默認風(fēng)格交掏。當(dāng)過渡到緊湊環(huán)境時,僅支持的樣式是兩種全屏風(fēng)格或UIModalPresentationNone刃鳄。返回UIModalPresentationNone告訴Presentation控制器忽視緊湊環(huán)境并繼續(xù)使用前面的Presentation風(fēng)格盅弛。如果是彈窗,忽視變更叔锐,提供類似iPad上的彈窗挪鹏。在圖13-4中展示了默認全屏自適應(yīng)和不適應(yīng),這樣你可以比較present結(jié)果愉烙。
要完全取代視圖控制器讨盒,實現(xiàn)代理的presentationController:viewControllerForAdaptivePresentationStyle: 方法。當(dāng)自適應(yīng)緊湊環(huán)境時步责,使用該方法插入導(dǎo)航控制器到視圖層級結(jié)構(gòu)或者加載為小空間設(shè)計的視圖控制器返顺。
實現(xiàn)自適應(yīng)popover的提示
當(dāng)從水平常規(guī)變?yōu)樗骄o湊環(huán)境時,彈窗需要額外的修改蔓肯。水平緊湊默認將彈窗改為全屏present遂鹊。通常通過點擊彈窗外區(qū)域dismiss彈窗,當(dāng)變?yōu)槿羛resent時無法dismiss彈窗蔗包”耍可以通過以下方式實現(xiàn):
- push彈窗的視圖控制器到存在的導(dǎo)航堆棧上。當(dāng)父導(dǎo)航控制器可用時调限,dismiss彈窗并將其視圖控制器push到導(dǎo)航堆棧上舟陆。
- 當(dāng)全屏?xí)r误澳,添加控件dismiss彈窗《帜龋可以添加控件到彈窗的視圖控制器上脓匿,但更好的選擇是使用presentationController:viewControllerForAdaptivePresentationStyle: 方法將彈窗從導(dǎo)航控制器中移除。使用導(dǎo)航控制器宦赠,則有一個模態(tài)界面和空間可以添加完成按鈕或其他控件dismiss內(nèi)容陪毡。
- 使用present控制器代理消除任何自適應(yīng)變化。獲取彈窗present控制器并分配代理實現(xiàn)adaptivePresentationStyleForPresentationController:方法勾扭。該方法返回 UIModalPresentationNone毡琉,導(dǎo)致彈窗繼續(xù)顯示為一個彈窗。更多信息妙色,參見presented視圖控制器適應(yīng)新風(fēng)格(Adapting Presented View Controllers to a New Style)桅滋。
響應(yīng)size變化
size發(fā)生變化的原因有很多,包括以下幾點:
- 底層窗口的尺寸改變身辨,通常因為方向改變丐谋。
- 父視圖控制器調(diào)整子視圖控制器的size。
- present控制器改變presented視圖控制器的size煌珊。
當(dāng)size發(fā)生變化時号俐,UIKit通過正常布局過程,自動更新可見視圖控制器的size和position定庵。如果使用Auto Layout約束指定視圖的size和position吏饿,app自適應(yīng)任何size變化并運行在不同屏幕尺寸的設(shè)備上。
如果Auto Layout約束不能滿足你的要求蔬浙,可以使用viewWillTransitionToSize:withTransitionCoordinator:方法改變布局猪落。還可以使用該方法創(chuàng)建額外動畫。例如畴博,在界面旋轉(zhuǎn)過程中笨忌,使用過度協(xié)調(diào)器的targetTransform 屬性來創(chuàng)建界面的逆轉(zhuǎn)矩陣。