寫在之前的大篇廢話
研究adaptivePresentationStyleForPresentationController和iPhone上popover一個popoverPresentationController的關系無果后,一怒之下翻譯該文檔,
希望不要浪費太多時間 -- 9月28號
結(jié)果學到了很多東西,雖然還沒解決問題 -- 9月29號
問題解決了,原來都在文檔里,只是我沒讀懂讀透 --9月30號
廢話:-----通過這次翻譯的經(jīng)歷,感覺到沉下心來做一件事的重要性,28號的時候無意間研究到iphone的popover,發(fā)現(xiàn)自己怎么也不能在iphone上做出一個popover出來,老是全屏,搗鼓了大半天,把度娘和谷歌翻了個遍,覺得確實是照著人家的帖子做的,為啥不出呢?
翻到ios官網(wǎng)的這篇文章,總覺得讀了沒有收獲,(我英語都認識,可是讀完也不知道它在說什么)但是又覺得它確實提到了我所說的問題,反正也挺無奈的,就決定逐字逐句的讀一讀這文章,看看是不是自己有什么沒懂的地方.
每句讀了也不了解的話,我都姑且照字翻譯了下,然后會去查閱相關的文檔,官網(wǎng)優(yōu)先,百度也問,也翻這本書:Programming.iOS.9.在逐步學習的過程中,發(fā)現(xiàn)了很多平時我掌握的似是而非的東西,如size classes,如vc間的present dismiss等等,雖然做ios已經(jīng)兩年了,這些東西每天都在弄,但是它很多細微的東西還沒有深入的了解.
慢慢的融會貫通幾個知識點,理解了很多東西,雖然這些東西平時沒人會問你為什么,找工作別人也不會問這么細,浪費時間想這些似乎沒有多大的意思,沒有弄些時尚流行的技術來得可以吹niub.但是還是感觸很深,很多簡單的功能,會做.但是為什么這么做,深層的意義在哪里,內(nèi)涵思想是什么,研究了這些細節(jié)后,才有所體會.之前還是很心浮氣躁,比如9月28號的時候,看了五六個帖子,覺得自己已經(jīng)會了popover的步驟,就是不出效果,快要放棄了.這兩天看了一些文檔,才領會了為啥這么做,為啥要寫代理,還可以舉一反三等等.讀的多了,發(fā)現(xiàn)某些大神的所謂深入帖子,也只是把官網(wǎng)的幾篇文檔綜合了一下,加上自己的總結(jié).可見編程其實和做學問差不多,要放下心中的浮躁,慢節(jié)奏的讀一些似乎沒用的東西.
問題的解決經(jīng)過:
之前照著這個帖子做的,http://m.itdecent.cn/p/e44542c38fc9 始終不能出現(xiàn)popover,總是全屏,我認為肯定是adaptivePresentationStyleForPresentationController這個函數(shù)出的問題,調(diào)試發(fā)現(xiàn)從來沒進入過,然后差點放棄了.
我也沒問過自己為什么一定要實現(xiàn)這個方法,原因是啥.就知道很多帖子都說了這個, 直到翻譯完了文檔,才知道:
其實在swift3中不是這個函數(shù)(OC中是上面那個函數(shù)),而是:
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle{
return .none
}
1) 它是UIViewController的屬性presentationController的代理UIPresentationControllerDelegate的函數(shù).
2) 同理,UIViewController的屬性popoverPresentationController的代理UIPopoverPresentationControllerDelegate,由于繼承了UIPresentationControllerDelegate的原因,所以也要實現(xiàn)這個方法.
關系如圖1-1-1:

實現(xiàn)了它頓時就好了.所以坑就在這里
這是我的代碼:
@IBAction func clickBtn(_ sender: AnyObject) {
let pop = PopViewController()
//這個屬性必須實現(xiàn),否則popoverPresentationController為nil
pop.modalPresentationStyle = .popover
//設置代理,用 adaptivePresentationStyle(for controller) 指定不要全屏顯示
pop.popoverPresentationController?.delegate = self
//popover 的大小
pop.preferredContentSize = CGSize(width:100, height:100)
//popover基于哪個view出來
pop.popoverPresentationController?.sourceView = btn
pop.popoverPresentationController?.sourceRect? = CGRect.zero
//? ? ? ? pop.popoverPresentationController?.sourceRect? = CGRect(origin:CGPoint(x:100,y:100) ,size:CGSize(width:0,height:0))
//popover的箭頭方向
pop.popoverPresentationController?.permittedArrowDirections = .down
self.present(pop, animated: true, completion: nil)
}
xib或者storyboard里的pop 不需要做任何改動.比如這個帖子寫的https://my.oschina.net/sayonala/blog/533888 ?都不用
效果:

翻譯之前的儲備
1. size classes
1) size classes 是ios8引進的的一種對布局的自適應的解決方案.可以從以下兩個方面理解:
對不同設備的屏幕尺寸,包括橫屏和豎屏,我們可以設定不同的view布局,系統(tǒng)會檢測到具體的設備,幫我們自動切換對應的布局.
對同一套布局,系統(tǒng)會檢測到具體的設備和屏幕方向,遵循autoulayout的設定,自動布局.
于是我們可以無視具體設備的尺寸和屏幕方向,根據(jù)size classes 的規(guī)定來布局了.
2) ?在ios8后,蘋果定義所有設備的size class只分為兩種屬性: 詳見枚舉UIUserInterfaceSizeClass
. 普通的(Regular)
. 緊湊的(Compact)
Any包含了上面兩種情況. 所以nib中的width:Any和height:Any代表:包含了所有情況.
如果在ios8后看到這種判斷設備和尺寸的代碼:就不太好(ios7時我剛?cè)腴Tios,看到我們公司項目中這么寫的,當時沒有size classes)
//iphone4 and iphone4s
if (UIScreen.main.bounds.height == 480) {
}
//iphone5 and iphone5s
else if (UIScreen.main.bounds.height == 568) {
}
那么具體設備尺寸和 Compact,Regular的對應關系是?
這張圖1-1來自于UITraitCollection的api文檔 https://developer.apple.com/reference/uikit/uitraitcollection

總結(jié)下:
1) ipad不管橫豎寬高size class都是regular,?
2) iPhone橫著時寬高size class都是compact,豎起來高會變成regular.
3)iPhone 6plus特殊點,不管橫豎 長邊就是regular,短邊是compact ?... iphone7不畫,因為它尺寸和iphone6s沒有變化.
現(xiàn)在ios10 nib編程已經(jīng)不用背這個了,為啥,見圖13-1. 它把尺寸和設備都形象化了
如果用代碼,我們還是要了解對應關系的,不然我們獲取出來了屏幕width和height的size class,還不知道當前設備是個啥情況呢.
2. trait - UITraitCollection和其接口UITraitEnvironment
上面說取屏幕width和height的size class,如何取?取出來后,我們可以根據(jù)不同的尺寸和橫豎屏,更改布局,如隱藏或者顯示某些view等.
trait英文是特性的意思,我理解就是UITraitCollection.也就是關于尺寸,設備屏幕的一系列屬性的大集合.
https://developer.apple.com/reference/uikit/uitraitcollection 這是 UITraitCollection的官方文檔
UITraitCollection是接口UITraitEnvironment的屬性.它包含了設備關于屏幕的眾多trait,size class也是其中一個屬性:
1) 水平和豎直上的size class,horizontalSizeClass,verticalSizeClass
2) 顯示縮放比 displayScale
3) 用戶設備的分類 userInterfaceIdiom(枚舉UIUserInterfaceIdiom).
public enum UIUserInterfaceIdiom : Int {
case unspecified ?//未定義
case phone // iPhone and iPod touch style UI
case pad // iPad style UI
case tv // Apple TV style UI ?apple做電視和車載,我還沒看到大陸哪里有買哇-_-
case carPlay // CarPlay style UI
}
UIScreen, UIWindow, UIViewController, UIPresentationController,UIView都實現(xiàn)了UITraitEnvironment接口,因此可以很方便的直接取用:
self.traitCollection
兩個函數(shù),在trait發(fā)生改變時被調(diào)用:
1.public func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) ?
它是接口UITraitEnvironment的方法.上面提到的UIScreen, UIWindow, UIViewController, UIPresentationController,UIView都可以實現(xiàn)它.當trait發(fā)生改變時,進入這個方法.我們通過判斷其屬性改變布局:
代碼:
//MARK: UITraitEnvironment
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)? {
//iphone 橫屏
if previousTraitCollection?.horizontalSizeClass == .compact &&? previousTraitCollection?.verticalSizeClass == .compact{
print("iPhone從橫屏->豎屏")
}
else if (previousTraitCollection?.horizontalSizeClass == .compact &&? previousTraitCollection?.verticalSizeClass == .regular){
print("iPhone從豎屏->橫屏")
}
}
注意:1) previousTraitCollection是之前的設備狀態(tài),不是當前的.而且有可能是nil,比如程序最開始啟動的時候還沒有之前狀態(tài)喲
? ? ? ? 2) 橫豎屏切換記得先打開手機設置中的橫豎屏開關
2.public func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator)
這個方法是接口UIContentContainer的方法,所幸UIViewController和UIPresentationController都實現(xiàn)了它. 它也是在trait改變時進入的.它先于traitCollectionDidChange被調(diào)用.
可以在里面寫動畫coordinator.animateAlongsideTransition ...
要調(diào)用super.willTransition(to: newCollection, with: coordinator). ?除非自己實現(xiàn)子viewcontroller的變化
代碼:
//MARK: UIContentContainer
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator){
super.willTransition(to: newCollection, with: coordinator)
coordinator.animateAlongsideTransition(in: self.view, animation: { (context) in
//動畫,隨便寫點啥把.
self.btn.titleLabel?.text = "gugu"
}) { (context) in
//iphone 橫屏
if newCollection.horizontalSizeClass == .compact &&? newCollection.verticalSizeClass == .compact{
print("iphone目前是橫屏")
}
else if (newCollection.horizontalSizeClass == .compact &&? newCollection.verticalSizeClass == .regular){
print("iphone目前是豎屏")
}
}
}
3. 3D touch和trait的關系
啰嗦一點,ios9中,在ViewController中判斷設備是否支持3Dtouch.就是這么寫的:
if(self.traitCollection.forceTouchCapability ==UIForceTouchCapabilityAvailable){
[self registerForPreviewingWithDelegate:self sourceView:self.view];
}
也是用到了trait的屬性哇.
要檢測3D touch是否被用戶關閉/打開了,也是在前面提到的函數(shù)里:
traitCollectionDidChange:
4. 不同的size class對應不同的圖片尺寸
在橫屏,豎屏,以及各種寬高的size class組合下,一張圖片需要有不同的尺寸.
這個要是自己用代碼寫,會多么惡心,要適配多少情況啊,幸好image asset功能之一就是干這個事情的,后面的譯文會講到這個,image asset有配置,可以對不同的size clas配置不同的圖片,見圖13-2
5. ViewController的present關系用到的size class的改變
這就是我掉坑的重點,了解了何為size class后,vc間的present關系中,presented viewController會在不同的設備環(huán)境下有不同的表現(xiàn). 如在regular環(huán)境下(ipad)的popover窗體,到了compact環(huán)境下,會變成全屏,而我們可以通過 UIViewController的屬性:popoverPresentationController來自定義presented viewController的變現(xiàn),讓它保持非全屏的模式.
譯文-終于開始翻譯了
原文地址:https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/BuildinganAdaptiveInterface.html
一個可適應的界面應該同時響應trait和size的改變.在view controller這個層級上,用trait來大體決定你要顯示的內(nèi)容和控件們用到的layout. 例如:當在size class之間切換時,你會改變view的屬性,顯示或者隱藏一些view.
適應trait的改變
trait可讓你在不同環(huán)境下配置不一樣的app顯示,大多數(shù)配置可以在storyboard上進行,少數(shù)還需要代碼協(xié)助.
用storyboard來配置不同的Size Classes
在IB上使用size classes是很簡單的,storyboard編輯器支持在不同的size classes上顯示界面.我們可以在特定的size classes上去掉某些view或者更改layout約束,你還可以創(chuàng)建image assets,把不同的image放在不同的size classes上.這樣,你就不用用好幾套代碼來做這種適配屏幕尺寸的事了,當app的size class變化時,UIKit會自動更新對應的界面.(很cool!)
ps:官網(wǎng)上了個老圖,為了與時俱進,上最新xcode8的界面

下面那一排設備,就是不同的size classes,是蘋果所有的設備尺寸,還可以選擇橫屏和豎屏
note: 沒安裝的view還是在你的view樹里面,還可以被操作到,只是不顯示罷了
(ps:不是很懂,這里的安裝是啥意思?是說在size class-a下我加了個view,size class-b下我讓其不顯示,但是view還是在么?這樣的話,如果多來幾套布局,整個包不會很大嗎?嘻嘻,不過似乎也只能這樣子喲)
image assets 是個很好的存儲圖片資源的地兒,每個image asset都有一個圖片的多個版本,每個版本都有特定的配置.除了可以對普通屏和視網(wǎng)膜屏指定不同的圖片,還可以對橫屏和豎屏指定不同的圖片.只要在image asset里面配置的圖片,UIImageView能自動選擇和當前的size classes配置相符的圖片.(ps:這就是為啥image asset大行其道的原因吧,以前都是放圖在bunlde里,現(xiàn)在image asset 會保存多一張圖的多個版本,略占空間.但是打包發(fā)布到App Store上后,store會采用Slicing技術,針對不同的設備生成不同的app變種,變種的不同圖片的選擇就是根據(jù)image asset來篩選的,所以實際上用戶設備中的app是不會很大的. 參考文檔:
1. https://developer.apple.com/library/prerelease/content/documentation/IDEs/Conceptual/AppDistributionGuide/AppThinning/AppThinning.html#//apple_ref/doc/uid/TP40012582-CH35-SW3
2. https://onevcat.com/2013/06/new-in-xcode5-and-objc/
)
圖13-2展示了image asset的配置,因為又是老圖,所以上個新的,好多屬性,重要是的是那個width class和height class,通過其組合可以對應不同size classes下的圖片.下個帖子一一研究下

改變子view controller的Traits
默認情況下,子viewController繼承父viewController的traits.不過trait和size classes一樣,不能要求所有子viewController都和父viewController完全一樣.例如:可能給子viewController的顯示空間沒有那么大,所以一個普通(regular)的父viewController會給它的幾個子viewController賦值緊湊(Compact)的size classe.
在容器view controller中,對父viewController調(diào)方法:setOverrideTraitCollection:forChildViewController: 來調(diào)整子viewController的trait
代碼13-1 展示如何創(chuàng)建trait并賦值給子view controller. 這段代碼寫父viewController中并最好只能執(zhí)行一次.子view controller的trait會一直保持,不被父viewController影響,直到它從view層中刪除.
UITraitCollection*horizTrait=[UITraitCollection
traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
UITraitCollection*vertTrait=[UITraitCollection
traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];
UITraitCollection*childTraits=[UITraitCollection
traitCollectionWithTraitsFromCollections:@[horizTrait,vertTrait]];
[selfsetOverrideTraitCollection:childTraitsforChildViewController:self.childViewControllers[0]];
問題來啦,trait屬性挺多的,被父viewController指定的屬性會在子viewController中一直保持,那么沒有指定的屬性呢?答案是遵循自父viewController的變化,和其保持一致.
如上面這段代碼,如果父viewController的水平size class發(fā)生變化,可是子viewController還是保持Regular
讓Presented View Controllers有新的風格
知識儲備
先說在present的意思,蘋果里面:
如果一個ViewController? A present了另一個ViewController? B, 則A稱為presentingViewController, B稱為presentedViewController. 它們通過UIViewController的這2個屬性可以訪問到彼此.如圖1-2

實際上,presentedViewController是被presentingViewController retain了
ViewController之間的present關系是一種? 模態(tài) 的關系, B的view覆蓋在A的view上,用戶點不到A,只能操作B,想要關閉B,只能在B上提供按鈕或者navigation item?
在iPhone上present B后,默認情況下,B的view就由自下往上的動畫效果展示出來,覆蓋在A的view上.
?動畫效果是可以改的:presentedViewController的屬性modalTransitionStyle
view是覆蓋還是替換,還是自定義類似popover的局部的顯示??
用presentedViewController的屬性modalPresentationStyle來配置.這里說下:
.FullScreen
默認的機制,presentedViewController的view全屏顯示
presentingViewController還是屏幕的根viewcontroller,但是它的view直接被presentedViewController的view替換了.
.OverFullScreen
presentedViewController的view全屏顯示
presentingViewController的view還在原來的地方,只是被presentedViewController的view覆蓋了,如果presentedViewController的view設置了透明度,還能看到它在下面呢
ios8只支持.FullScreen和OverFullScreen
.PageSheet
presentedViewController的view全屏顯示
在iPad 豎屏上,它會略短一截,在statusbar的下面留出空白,ipad橫屏和iphone6 pluas上,它左右也會短一截,
present的函數(shù):
open func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (@escaping () -> Swift.Void)? = nil)
storyboard的拉線:
Present Modally 和Present as popover ,如圖1-3

關閉的函數(shù)(這么說其實不專業(yè),ios里的函數(shù)都是消息,發(fā)送給對象):
open func dismiss(animated flag: Bool, completion: (@escaping () -> Swift.Void)? = nil)
關閉時,presentingViewController收到該消息,presentedViewController的view從屏幕上撤下,不再覆蓋presentingViewController的view,然后presentedViewController的內(nèi)存被釋放. 嘻嘻!別繞暈了,很簡單的
值得一提的是:這個消息可以發(fā)送給presentingViewController也可以發(fā)送給presentedViewController. iOS的runtime會把這個消息最終傳遞到presentingViewController.所以,最終響應該消息的是presentingViewController
扯起來的話,可說的內(nèi)容還挺多的,雖然平時關閉一個vc,dismiss就萬事大吉,面試時基本也不會有人問,不過多了解一點總是好的.-_-
1. 每個presentingViewController最多只能有一個presentedViewController.如果一個presentingViewController的presentedViewController已經(jīng)不為nil了.你再給它發(fā)送present(:animated:completion:)消息,則不會發(fā)生任何反應,completion handler也不會被調(diào)用.runtime會給你個警告
2. presentedViewController也能再present view controller, 這就形成了一個鏈,如果你對中間的B發(fā)送dismiss(:completion) 消息,則C會關閉掉,B不會,因為此刻它也是一個presentingViewController ,如圖1-4

3. 如果給一個presentedViewController為nil的view controller發(fā)送dismiss(:completion) 消息,則不會發(fā)生任何事,但是completion handler會被調(diào)用
注意:
1) 默認情況下,presentedViewController覆蓋presentingViewController的全部view
1) iOS8后,無論iPhone還是iPad都可讓presentedViewController只占據(jù)presentingViewController的一個subview的空間,而不是整個view區(qū)域
2) IOS7后,無論iPhone還是iPad都可讓presentedViewController只占據(jù)presentingViewController的一部分區(qū)域,而不是整個view區(qū)域
繼續(xù)翻譯
presentedViewController 會自適應水平方向上的的regular和compact.比如:當從水平的regular變成水平的compact時,UIKit默認自動把ViewController的presentation style變成了UIModalPresentationFullScreen,自定義presentation style是由presentation controller進行調(diào)整的.
啰嗦幾句:
presentation controller和presentation style是啥呢?
UIViewController有個擴展,寫了2個只能get的屬性:
1) presentationController
2) popoverPresentationController? (它其實繼承于presentationController,是presentationController的popover的擴展)
它們不是繼承于UIViewController的,而是繼承于NSObject的.它們負責管理一個UIViewController的present的某些屬性.
注意:
一定要先給UIViewController的modalPresentationStyle屬性賦值,上面2個屬性才不會是nil的.
1) 如果modalPresentationStyle是.popover,則popoverPresentationController被賦值
2) 如果modalPresentationStyle是其他枚舉值,則presentationController被賦值
繼續(xù)翻譯
對于某些app,全屏的present會造成困擾.比如,如果點擊一個popover的bounds的外面空白地方,會關掉這個popover,但是如果這個popover已經(jīng)占領了全屏,就沒法關閉它了,就如13-3所示.如果默認的自適應style機制不能滿足你的需要,你應該告知UIKit用不同的style來present

如何自定義presenting style呢? 首先得給presentedViewController的presentationController或者popoverPresentationController設置delegate,當自適應變化開始時,delegate的方法會被觸發(fā).它會返回不同的presenting style,它還可以讓presentationController交替顯示不同的ViewController(-_- delegate略強大)
在delegate中實現(xiàn)UIAdaptivePresentationControllerDelegate的代理方法:
optional public func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle
頭文件的注釋道:在ios8里,只支持2個style
UIModalPresentationFullScreen:全屏,
UIModalPresentationOverFullScreen.
注意吧.官網(wǎng)上寫的是:adaptivePresentationStyleForPresentationController:?如果真直接copy過去實現(xiàn)這個,就完蛋了,我就栽在這里了.
代碼:
//MARK: UIPopoverPresentationControllerDelegate
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle{
return .none
}
當app轉(zhuǎn)入compact的環(huán)境時,只支持全屏或者 無 (UIModalPresentationNone),返回.none就是告訴presentation controller忽略compact的環(huán)境,保持之前的present style,在任何設備上都如此,13-4展示了全屏和非全屏的效果,以做比較:

delegate的另一個方法
public func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController?
當進入了compact環(huán)境時,你可以在你的view層次里insert一個navigation controller,或者load一個新的view controller,來替換本該present的view controller
(不好意思,在iphone6上沒調(diào)試出來,實現(xiàn)了沒進入過該函數(shù),我還要進一步研究)
實現(xiàn)適應性彈出框(Popover)的建議
當從水平Regular變成水平Compact環(huán)境時,Pop over 需要額外的改動.水平Compact環(huán)境下,默認的行為是popover會變成全屏.因為popover的關閉方法是點擊它bounds之外的空白處,而全屏就無法做到這一點.我們可以通過下面的做法來改變這種情況:
1) 讓popover到navigation的棧里面
加一個navigation controller,通過navigationBarItem來dismiss它
2) 加控件來dismiss全屏的popover
可以通過加控件來dismiss全屏的popover,但是更多的辦法是用navigation controller換掉popover, 函數(shù)是:
presentationController:viewControllerForAdaptivePresentationStyle:
用navigation controller給你的模態(tài)界面加上一個Done按鈕或者其他控件來dismiss掉這個界面.
3) 用presentation controller的delegate消滅一切系統(tǒng)的的自適應
這就是網(wǎng)上大多數(shù)的帖子做法,他們經(jīng)常通過簡潔的方式,直接指導你實現(xiàn)步驟,但是不說為啥,對看帖子的人來說,提升不大,換而言之,看的人應該多思考多查閱,不能讓別人把什么都擺在你面前,那也做不到.除非是時間來不及,項目逼死人.--說給自己聽的!自勉!
作為popover的UIViewController,設置它的屬性popoverPresentationController的delegate
實現(xiàn)delegate的func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle方法,返回:UIModalPresentationNone (.none) 更多的信息,請參考:https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/BuildinganAdaptiveInterface.html#//apple_ref/doc/uid/TP40007457-CH32-SW6
對Size 的變化做出反應
size會因為很多原因發(fā)生變化,包括下面的:
1) 窗口的尺寸變化,大多數(shù)時候由轉(zhuǎn)動屏幕引起
2) 父view controller 重新設置了子view controller的尺寸
3) presentationController改變了它顯示的ViewController的尺寸
當size發(fā)生變化時,UIKit根據(jù)layout的約束,自動改變當前顯示的view controller層級的的尺寸和位置,如果你使用auto layout來指定view的size和位置,你的app會自動適應任何size和設備帶來的變化.
如果你的autoulayout 還不足以達到你所想要的效果, 你可以用viewWillTransitionToSize:withTransitionCoordinator: 來改變你的布局,你可以創(chuàng)建額外的動畫,這些動畫會和size-change的動畫一起運行.例如:當轉(zhuǎn)屏時,調(diào)用UIViewControllerTransitionCoordinator的屬性targetTransform?來創(chuàng)建一個反轉(zhuǎn)矩陣給某些需要的顯示控件使用
demo:https://github.com/ivychenyucong/TestPopover
參考: http://www.cnblogs.com/zhw511006/p/3998534.html ? 對ios8的size classes講解的很清楚到位
https://onevcat.com/2014/07/ios-ui-unique/ ?size class的解釋很清楚