iOS: UISplitViewController cannot be pushed to UINavigationController
One workaround if you still need to navigate to splitView
is to create an empty UIViewController
and add the splitViewController
as a child
/// This should be in your parent controller
/// that you to navigate your splitView
func navigateToSplit() {
let container = UIViewController()
let splitView = MySplitViewController() // ===> Your splitViewController
container.addAsChildViewController(type: splitView, attached: container.view)
navigationController?.pushViewController(container, animated: true)
}
extension UIViewController {
/// this add a child controller to the view of another controller
func addAsChildViewController(type controller: UIViewController, attached toView: UIView) {
// Add Child View Controller
addChild(controller)
// Add Child View as Subview
toView.addSubview(controller.view)
// Configure Child View
controller.view.frame = toView.bounds
controller.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Notify Child View Controller
controller.didMove(toParent: self)
}
}
Pushing a split view controller through navigation controller is not possible, but there is a alternative that get the job done
You can create a view controller and add the split view controller as a child and then you can push that created view controller through the navigation controller. It will show your split view controller and you can work with both master and detail.
*remember to add the yoursplitviewcontroller class to custom class in storyboard
note splitcontroller -> (master, detail)
let splitVC = getViewController(storyBoardName: "story board name", viewControllerName: "split view controller identifier") as! yoursplitviewcontroller
view.addSubview(splitVC.view)
view.bounds = splitVC.view.bounds
addChild(splitVC)
func getViewController(storyBoardName: String, viewControllerName: String) -> UIViewController{
let storyBoard = UIStoryboard(name: storyBoardName, bundle: nil)
return storyBoard.instantiateViewController(identifier: viewControllerName)
}
To display a SplitViewController you'll need to use setRootViewController. This is because a SplitViewController needs to be the root view controller.
From Apple's Documentation:
A split view controller must always be the root of any interface you create. In other words, you must always install the view from a UISplitViewController object as the root view of your application's window. The panes of your split-view interface may then contain navigation controllers, tab bar controllers, or any other type of view controller you need to implement your interface.
To get back you'll need to use setRootViewController to go back to the earlier page. I ran into this problem when I converted my iPhone app to universal, and ended up using a navigation controller for the iPhone and setRootViewController for the iPad version. It's a bit of a bummer because you can't animate it nicely without a bit of fudging.