Dismissing a Popover from a UISplitViewController
Tuesday, February 28th, 2012This is more or less a “WTF? Is this really how hard this is?” kind of a post. It wouldn’t fit in < 140 chars, so it’s not on Twitter. I encourage you to comment if you know a better way to do this.
The Problem
The HIG states that we should avoid having multiple UIPopovers displaying at once… so when one displays, another should disappear. Sadly, when using a UISplitViewController it appears that the provided UIPopoverController for the master view controller does not do this automatically. Meaning, if you have the device in portrait mode, and you bring up another popover, the master view controller popover does not automatically dismiss.
It would be awesome if there was some global flag you could set that would just say “All UIPopOvers… if another one displays, dismiss!” But alas there isn’t. (Hmmm… a category opportunity?)
In any case, it seems, the easiest way to do this is perhaps to have all your popovers send out a notification when they are displaying, so all other popovers can close themselves. This includes the UISplitView popover… but therein lies the rub.
You see, to get to the popover that’s displayed with the UISplitView, you have to set a delegate to handle the method -splitViewController:popoverController:willPresentViewController: and save the popover controller that’s passed. For example:
-(void)splitViewController:(UISplitViewController *)svc
popoverController:(UIPopoverController *)pc
willPresentViewController:(UIViewController *)aViewController
{
self.popover = pc;
}
The trouble is, if you do this, you lose the automatic adding and removing of the button to display this popover in your toolbar on your Detail View controller.
The Cure?
The only way to fix this, is to then ALSO implement the following delegate methods:
-(void)splitViewController:(UISplitViewController *)svc
willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)button
{
NSMutableArray *toolbarItems =
[NSMutableArray arrayWithArray:
self.detailViewController.toolbar.items];
[toolbarItems removeObject:button];
[self.detailViewController.toolbar setItems:toolbarItems];
}
-(void)splitViewController:(UISplitViewController *)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem *)barButtonItem
forPopoverController:(UIPopoverController *)pc
{
NSMutableArray *toolbarItems =
[NSMutableArray arrayWithArray:
self.detailViewController.toolbar.items];
[toolbarItems insertObject:barButtonItem atIndex:0];
[self.detailViewController.toolbar setItems:toolbarItems];
}
Which seems like an awful lot of work just to dismiss my damn popover. Surely I must be doing something wrong or missing something obvious. Can someone enlighten me?

