Sep 16

The iPad UI Element Guidelines section of the iPad’s Human Interface Guideline forbids displaying more than one popover element at a time. Like this:


Since there’s no explicit support in UIKit for avoiding this, I thought I’d show one way to remain in compliance with the HIG.

In the app depicted above, the left popover is the standard list component (left side) of a split view controller. It is shown in portrait mode when you tap the Bookmarks button. The popover on the right is an alert sheet that appears when you tap the action button.

The left popover is retained in the property self.popoverController, per Apple’s split view controller template. For the right popover I store the action sheet in the actionButtonActionSheet attribute.

When the action button is tapped this code is called:

- (IBAction)actionButtonSelected:(id)sender {
  // Dismiss other popovers, if visible
  if ([self.popoverController isPopoverVisible]) {
    [self.popoverController dismissPopoverAnimated:YES];
  actionButtonActionSheet = [[UIActionSheet alloc] initWithTitle:nil 
                                               otherButtonTitles:NSLocalizedString(@"button.add.bookmark", @""),
                                                                 NSLocalizedString(@"", @""),
                                                                 NSLocalizedString(@"button.mail.bookmark", @""),
                                                                 NSLocalizedString(@"button.share.facebook", @""),
                                                                 NSLocalizedString(@"button.share.twitter", @""), nil];
  [actionButtonActionSheet showFromBarButtonItem:sender animated:YES];
  [actionButtonActionSheet release];

The important part for this discussion is the first couple of lines that dismiss the other popover if it’s visible.

For the opposite case when the Bookmarks button is tapped, you need to override the willPresentViewController method:

- (void)splitViewController:(UISplitViewController *)svc popoverController:(UIPopoverController *)pc willPresentViewController:(UIViewController *)aViewController {
  // Dismiss other popovers, if visible
  if (actionButtonActionSheet.visible) {
    [actionButtonActionSheet dismissWithClickedButtonIndex:-1 animated:YES];

If your app has more than two buttons that launch popovers, then you should extract the code that dismisses other popovers into one method that you can call from all button action methods.

written by Nick \\ tags: , , ,

Leave a Reply