Xcode自帶的Master-Detail模板應(yīng)用,在iPad和iPhone上有著不同的展示方式。今天來淺要介紹下如何在橫屏?xí)r,使得SplitView在iPhone中的表現(xiàn)與在iPad中的保持一致。
iPad和iPhone中的不同
準(zhǔn)備工作
打開Xcode,使用iOS->Application->Master-Detail Application模板創(chuàng)建一個(gè)App,取名隨意。
運(yùn)行后界面比較
以下分別是初始化的App在iPad、iPhone 6 Plus、iPhone 6中的橫屏截圖。



可以看到,App在iPad和Plus中的橫屏表現(xiàn)幾乎一致,除了Plus中沒有顯示最上面的狀態(tài)欄和新增了Detail View左上角的按鈕。但在其它iPhone中時(shí),都只顯示Master View,不同時(shí)顯示Master和Detail View。這是由于什么原理造成的呢?
原理探究
Size Classes
想到iPhone 6 Plus、iPhone 6的屏幕尺寸不同,對應(yīng)的Size Class也不盡相同,故找來各個(gè)iOS設(shè)備的Size Class做對比,如下表所示:
| 寬 | 高 | 設(shè)備與方向 |
|---|---|---|
| Compact | Compact | 除了Plus以外的所有橫屏iPhone |
| Compact | Regular | 所有的豎屏iPhone |
| Regular | Compact | 橫屏的Plus |
| Regular | Regular | iPad,不管橫豎屏 |
可以看到,在橫屏狀態(tài),iPad的寬和高都是Regular,Plus的寬是Regular,高是Compact,其余iPhone的寬和高都是Compact。故有可能只有在設(shè)備寬是Regular時(shí),SplitView才會默認(rèn)同時(shí)顯示Master和Detail View。因此只要在iOS設(shè)備的interface environment發(fā)生改變時(shí),檢測設(shè)備的長和寬,若都為Compact,則將寬設(shè)為Regular,即可改變SplitView的默認(rèn)collapse做法。
traitCollectionDidChange
當(dāng)interface environment發(fā)生改變時(shí),traitCollectionDidChange方法會被調(diào)用,可以在這里進(jìn)行相關(guān)設(shè)置。
首先在Storyboard中拖入一個(gè)Navigation Controller,將其設(shè)為Initial View Controller,并將原先為Initial View Controller的Split View Controller設(shè)為它的root view controller。這樣做是為了用新加的Navigation Controller來控制Split View Controller的traitCollection change行為。同時(shí)將Navigation Controller的Shows Navigation Bar選項(xiàng)取消勾選,使其不影響原有視圖表現(xiàn)形式。

創(chuàng)建基于UINavigationController的RootViewController類,將其與新添加的Navigation Controller相對應(yīng)。在該類中實(shí)現(xiàn)traitCollectionDidChange方法:
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
let splitViewController = self.viewControllers[0]
if self.traitCollection.verticalSizeClass == .Compact && self.traitCollection.horizontalSizeClass == .Compact {
let trait = UITraitCollection(horizontalSizeClass: .Regular)
self.setOverrideTraitCollection(trait, forChildViewController: splitViewController)
} else {
self.setOverrideTraitCollection(nil, forChildViewController: splitViewController)
}
}
以上代碼的作用是,當(dāng)檢測到設(shè)備的長和寬都為Compact時(shí),則這時(shí)候是在除了Plus以外的橫屏iPhone中運(yùn)行App,將其寬設(shè)為Regular,SplitView能夠同時(shí)顯示Master和Detail View;否則,不做任何重載。
AppDelegate微調(diào)
同時(shí)需要在AppDelegate.swift的didFinishLaunchingWithOptions函數(shù)進(jìn)行微調(diào),如下所示:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let rootViewController = self.window!.rootViewController as! RootViewController
let splitViewController = rootViewController.viewControllers[0] as! UISplitViewController
// let splitViewController = self.window!.rootViewController as! UISplitViewController
let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem()
splitViewController.delegate = self
return true
}
運(yùn)行結(jié)果
在iPhone 6下重新運(yùn)行App,橫屏?xí)r的截圖如下所示,說明修改成功。

結(jié)語
以上是我的一些經(jīng)驗(yàn)與心得,若有不足之處,請予指正。希望這篇文章對你有所幫助_。