I usually create my projects without IB-stuff. The first thing I do is to strip off all references to xibs, outlets updated plist, etc and so forth. No problems, works great
Swift 5.2
iOS 13
Both master and detail view controllers are embedded in navigation controllers
let splitViewController = UISplitViewController()
splitViewController.delegate = self
let masterVC = MasterViewController()
let detailVC = DetailViewController()
let masterNavController = UINavigationController(rootViewController: masterVC)
let detailNavController = UINavigationController(rootViewController: detailVC)
splitViewController.viewControllers = [masterNavController,detailNavController]
You can put this code in your AppDelegate's (or in SceneDelegate if your target is iOS 13.0+)didFinishLaunchingWithOptions
function. Just remember to make the splitViewController
your rootViewController
like this
self.window!.rootViewController = splitViewController
Declare your splitviewcontroller in your delegate header, use something like this in your didfinishlaunching
ensure you add the UISplitViewControllerDelegate to the detailedViewController header file and that you have the delegate methods aswell. remember to import relevant header files
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
splitViewController = [[UISplitViewController alloc] init];
rootViewController *root = [[rootViewController alloc] init];
detailedViewController *detail = [[detailedViewController alloc] init];
UINavigationController *rootNav = [[UINavigationController alloc] initWithRootViewController:root];
UINavigationController *detailNav = [[UINavigationController alloc] initWithRootViewController:detail];
splitViewController.viewControllers = [NSArray arrayWithObjects:rootNav, detailNav, nil];
splitViewController.delegate = detail;
[window addSubview:splitViewController.view];
EDIT - as per Scott's excellent suggestion below, don't add to the windows subview, instead
[self.window setRootViewController:(UIViewController*)splitViewController]; // that's the ticket
[window makeKeyAndVisible];
return YES;
}
//detailedView delegate methods
- (void)splitViewController:(UISplitViewController*)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController:(UIPopoverController*)pc
{
[barButtonItem setTitle:@"your title"];
self.navigationItem.leftBarButtonItem = barButtonItem;
}
- (void)splitViewController:(UISplitViewController*)svc
willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
self.navigationItem.leftBarButtonItem = nil;
}
I also prefer code to IB ;-)
I had just met the same problem. make sure that your child viewController of splitview can Autorotate to interface orientation.
you can change the function in your childViewController like this:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
then the master view will be shown.
Oldish thread, but thought I'd spare reader time + grief when the above technique fails to produce a UISplitViewController that responds correctly to device orientation change events. You'll need to:
Rather than add the UISplitViewController's view to the main window,
[window addSubview:splitViewController.view]; // don't do this
instead set the main window's root controller to the UISplitViewController:
[self.window setRootViewController:(UIViewController*)splitViewController]; // that's the ticket
Adding the splitviewcontroller's view as a subview of the main window (barely) allows it to co-present with sibling views, but it doesn't fly with UISplitViewController's intended use case. A UISplitViewController is a highlander view; there can only be one.