I’ve been working on porting Taipan! to the iPad, so I recently installed a UISplitViewController
as the root of my controller hierarchy. There was a somewhat non-obvious trick to getting it working (spoiler warning: orientations), so I thought I’d write a short piece about it.
The Easy Way
The Apple documentation states:
The easiest way to integrate a split view controller into your application is to start from a new project. The Split View-based Application template in Xcode provides a good starting point for building an interface that incorporates a split view controller. Everything you need to implement the split view interface is already provided. All you have to do is modify the array of view controllers to present your custom content. The process for modifying these view controllers is virtually identical to the process used in iPhone applications.
Everything written there is absolutely true, but since I wasn’t starting from a new project, it wasn’t relevant to me. I followed the instructions for adding a UISplitViewController
to an existing project, but the result didn’t work. The problem turned out to lie with interface orientations.
Autorotation
All UIViewControllers
respond to the shouldAutorotateToInterfaceOrientation:
selector — but, as Apple puts it:
By default, this method returns YES
for the UIInterfaceOrientationPortrait
orientation only. If your view controller supports additional orientations, override this method and return YES for all orientations it supports.
The default behavior worked just fine for the iPhone version of the game, as landscape mode didn’t make much sense for my UI. Unfortunately, it turns out that UISplitViewControllers
don’t work well if their child controllers don’t support all (or most?) of the possible orientations. Their behavior seems a little unpredictable: black screens, views drawn only in some orientations, views drawn only after a rotation, &c., but it’s always ugly and wrong.
Solution
The first-order solution is simple enough: just include the following code in all the view controllers displayed inside the UISplitViewController
:
// Override to allow orientations other than the default portrait orientation for iPad.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (interfaceOrientation == UIInterfaceOrientationPortrait);
}
(Be sure to include this code in any descendant view controllers, e.g., view controllers pushed onto navigation controllers displayed inside the split view controller.)
The complete solution is a little tricker, as all affected view controllers must be recoded to display properly in all orientations. Some may work automatically, but, at a minimum, you’ll probably be revisiting some NIBs.