In my UISplitViewController
the master controller is a UINavigationController
.
When in portrait mode I would like to keep the navigation controller visible as long as the user navigates upwards (using the back button). As soon as an item from the table view of the navigation controller is selected, I want to dismiss the popover.
How can I achieve this? How can my UITableViewController
know if it is inside a popover, and if yes, dismiss itself?
3 Answers
Make your main view controller a UISplitViewControllerDelegate
(if it isn't already) and wire it up to the UISplitViewController's delegate
outlet.
Create a UIPopoverController
variable in your main view controller:
// MyViewController.h
@interface MyViewController : UIViewController <UISplitViewControllerDelegate> {
UIPopoverController *popoverController;
}
@property (retain, nonatomic) UIPopoverController *popoverController;
// MyViewController.m
@synthesize popoverController;
Implement the following UISplitViewControllerDelegate methods:
// Called when rotating to portrait
- (void)splitViewController:(UISplitViewController*)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController:(UIPopoverController*)pc {
// Popover controller is visible in portrait
self.popoverController = pc;
}
// Called when rotating to landscape
- (void)splitViewController:(UISplitViewController*)svc
willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
// No popover controller in landscape view
self.popoverController = nil;
}
In your own handler in the main view controller (the one that gets called when a naviation item is selected in the table view):
- (void)navigationControllerSelectedItem:(id)item {
// If a popover controller is visible, hide it
if (popoverController) {
[popoverController dismissPopoverAnimated:YES];
}
}
And don't forget to release that variable:
- (void)dealloc {
self.popoverController = nil;
[super dealloc];
}
Hope that helps!

- 406
- 3
- 4
-
Hi mkerley, I tried above solution but it's not calling UISplitViewControllerDelegate methods.Can you please help me? – Minakshi Apr 01 '14 at 05:56
-
I've used this approach before but now these methods are deprecated. Do anyone have an updated solution? – Janne Apr 03 '20 at 12:31
The IOS 6.0 SplitView template has this built in. The detail view tracks the orientation and the MasterViewController popover.
Simply set the detailItem and the popover disappears if appropriate. There is even a check if you are using the same detaiItem so no page setup and refresh work gets done.
self.detailViewController.detailItem = self.detailViewController.detailItem;

- 1,428
- 14
- 21
The standard iPad sample for SplitViewController in iOS5 does about the same as the elaborate answer, but the popoverController is called masterPopoverController.
And creating the property iOS5 style as _popoverController does not work, because there as already an ivar with that name in UIViewController.h.

- 1,339
- 12
- 25