December 14 2011
Modal views in universal iOS apps
On the iPhone, it’s quite normal to have an app slide a sheet up to create something or change settings. But on the iPad, that same view should be displayed in a popover. In a universal app, the key is shared code and XIBs for both approaches.
The code below is all that I needed to have a Settings sheet appear correctly in both an iPhone and iPad app. I simply identify the device type and then either present a popover controller or a modal view controller, using the same XIB. Clean code. Consistent interface.
// Main View Controller
- (IBAction)showSheet:(id)sender {
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
// iPad
if (!self.popoverController.popoverVisible) {
self.popoverController = [[[UIPopoverController alloc] initWithContentViewController:self.myNavigationController] autorelease];
self.popoverController.popoverContentSize = CGSizeMake(400, 400);
self.popoverController.contentViewController.contentSizeForViewInPopover = CGSizeMake(400, 400);
self.popoverController.delegate = self;
// Present the popover from the bar button.
[self.popoverController presentPopoverFromBarButtonItem:self.navigationItem.rightBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
else {
// iPhone
[self.navigationController presentModalViewController:self.myNavigationController animated:YES];
}
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)aPopoverController {
[self.popoverController dismissPopoverAnimated:YES];
}
- (MyNavigationController *)myNavigationController {
if (myNavigationController == nil) {
self.myNavigationController = [[UINavigationController alloc] initWithRootViewController:self.mySheetController] autorelease];
}
return myNavigationController;
}
- (MySheetController *)mySheetController {
if (mySheetController == nil) {
self.mySheetController = [[MySheetController alloc] initWithNibName:@"MySheetView" bundle:nil] autorelease];
}
return mySheetController;
}
// Sheet View Controller
- (void)viewWillAppear:(BOOL)animated {
self.contentSizeForViewInPopover = CGMakeSize(400, 400);
[super viewWillAppear:animated];
}