@zhangyuhangk
2015-07-22T06:51:16.000000Z
字数 3972
阅读 5296
UISplitViewController
iOS8
iOS
Storyboard如下:
左边是split view controller
右上是master (或primary) view controller
右下是detail (或secondary) view controller
iOS8加入了size classes,并且允许iPhone上使用UISplitViewController。
当水平方向的size class为Compact时,split view显示为合并
当水平方向的size class为Regular时,split view显示为展开
可以使用iPhone6 Plus模拟器来运行,因为它竖屏的时候是Compact,横屏的时候是Regular。只要转一下就可以切换了,比较方便(以下均以iPhone6 Plus模拟器为例)。
合并和展开的时候会触发哪些事件或方法呢?
先设置delegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
splitViewControler.delegate = self
return true
}
实现UISplitViewControllerDelegate
extension AppDelegate: UISplitViewControllerDelegate {
func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool {
if some_condition {
return false // collapse
}
return true // do not collapse
}
func splitViewController(splitViewController: UISplitViewController, separateSecondaryViewControllerFromPrimaryViewController primaryViewController: UIViewController) -> UIViewController? {
if some_condition {
return MySecondaryViewController()
}
return nil
}
}
split view controller合并时会调用splitViewController:collapseSecondaryViewController:ontoPrimaryViewController函数。如果不实现该函数或者返回false,则secondary view controller会合并到primary view controller上去。若返回true,则表示你自己处理了这个合并的行为,系统就不会再合并了。
展开时则调用splitViewController:separateSecondaryViewControllerFromPrimaryViewController函数。若不实现该函数或返回nil,则将原来合并到primary view controller上的secondary view controller拆分出来。
split view默认是展开的状态,当应用以竖屏启动时,系统会在显示前就作一次合并的动作。
上面说到split view controller会将secondary view controller合并到primary view contrller上,但是怎么实现合并的呢?
如果primary view contrller是个UINavigationController(大部分情况它都是),那secondary view contrller就是直接被push上去(即使secondary view contrller本身也是个UINavigationController)。
那如果primary view controller只是个普通的UIViewController呢?
iOS8为UIViewController添加了两个函数来响应合并和展开:
func collapseSecondaryViewController(secondaryViewController: UIViewController, forSplitViewController splitViewController: UISplitViewController)
func separateSecondaryViewControllerForSplitViewController(splitViewController: UISplitViewController) -> UIViewController?
行为和UISplitViewControllerDelegate的两个函数类似
默认的实现:
合并时,primary view controller只保存secondaryViewController的引用,UI没变化,还是只显示primary view controller
展开时,把secondaryViewController展开回来
UINavigationController重写了上述两个函数,相应地调用了pushViewController和popViewController
注意:如果primary和secondary view controller都是UINavigationController。如下图:
横屏时,各自显示为navigation view controller,并且 title的值不同,navigation bar的titleTextAttributes也不同
合并时,secondary view controller显示在上面,包括title。但是此时navigation bar的样式(比如tintColor或titleTextAttributes)用的是primary view controller的!
如果希望合并后仍然使用secondary view contrller的样式,就需要在代码中显式赋值了。
extension AppDelegate: UINavigationControllerDelegate {
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
UIView.animateWithDuration(0.25) {
let secondaryNavigationController = viewController as? UINavigationController
self.applyColorFromNavigationController(secondaryNavigationController, toNavigationController: navigationController)
}
}
private func applyColorFromNavigationController(fromVC: UINavigationController?, toNavigationController toVC: UINavigationController) {
toVC.navigationBar.titleTextAttributes = fromVC?.navigationBar.titleTextAttributes
toVC.navigationBar.tintColor = fromVC?.navigationBar.tintColor
}
}
辅助函数applyColorFromNavigationController:toNavigationController函数中的fromVC如果传nil,则toVC.navigationBar的titleTextAttributes和tintColor均会被置为nil,效果相当于重置为系统默认样式。
此处选择在UINavigationControllerDelegate的navigationController:willShowViewController:animated函数中设置样式。该函数在合并和展开时都会被调用。viewController参数就是即将要成为topViewController的view controller。
当然也可以在UISplitViewControllerDelegate中设置,只是这样实现会稍麻烦。
第一次写近似教程的笔记,感觉不太自然,文章结构也乱七八糟,不晓得别人能不能看得懂。希望这些文章能帮到其他在自学路上奋斗的人吧。我会再努力,争取写得像样一点 ^_^
(不晓得用Cmd Markdown写的东西别人能不能评论呢?)