In XCode 6, if you create a new project based on the Master-Detail Application template, you get a universal storyboard that is supposed to be good for all devices.
When
Re-watching videos from WWDC14 I think I've found a better answer.
Here is the the code of the custom UISplitViewController :
import UIKit
class CustomSplitViewController: UISplitViewController {
override func showDetailViewController(vc: UIViewController!, sender: AnyObject!) {
if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact) {
if let tabBarController = self.viewControllers[0] as? UITabBarController {
if let navigationController = tabBarController.selectedViewController as? UINavigationController {
navigationController.showViewController(vc, sender: sender)
return
}
}
}
super.showDetailViewController(vc, sender: sender)
}
}
Do not forget to the set the custom class in the storyboard.
Tested in the simulator of iPhone 6, iPhone 6+ and iPad Air and worked as expected.
The docs state when the split controller is collapsed, it handles showDetail
by calling show
on the master view controller, which in your case is a tab controller. You need to forward that on to the child nav controller as follows:
- (void)showViewController:(UIViewController *)vc sender:(id)sender{
[self.viewControllers.firstObject showViewController:vc sender:sender];
}
This forwards it on to the nav controller in the first tab.
Unfortunately, the selected answer didn't work for me. However, I did eventually manage to solve the problem:
UISplitViewController
and set the new class in Interface Builder.Make the new class conform to UISplitViewControllerDelegate
:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.delegate = self
}
Implement these two methods:
func splitViewController(_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController:UIViewController,
onto primaryViewController:UIViewController) -> Bool {
return true
}
func splitViewController(_ splitViewController: UISplitViewController,
showDetail vc: UIViewController,
sender: Any?) -> Bool {
if splitViewController.isCollapsed {
guard let tabBarController = splitViewController.viewControllers.first as? UITabBarController else { return false }
guard let selectedNavigationViewController = tabBarController.selectedViewController as? UINavigationController else { return false }
// Push view controller
var detailViewController = vc
if let navController = vc as? UINavigationController, let topViewController = navController.topViewController {
detailViewController = topViewController
}
selectedNavigationViewController.pushViewController(detailViewController, animated: true)
return true
}
return false
}