淺析Split View Controller的collapse特性

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中的橫屏截圖。

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)形式。

取消勾選Shows Navigation Bar

創(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的截圖如下所示,說明修改成功。

iPhone6橫屏截圖

結(jié)語

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容