After experimenting I wondered what would happen if I attempted to create my own swipe gesture to open the master view. This works perfectly, and it doesn't fail when using sliders!
So, in the app delegate I suppress the default swipe gesture:
splitViewController.presentsWithGesture = NO;
When the detail view is loaded, I create a swipe gesture:
- (void)viewDidLoad
{
[super viewDidLoad];
UISwipeGestureRecognizer *swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipe:)];
swipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeGestureRecognizer];
[self configureView];
}
In splitViewController:willHideViewController:withBarButtonItem:forPopoverController: I store the references that I need to open the master view myself:
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
// Add the bar item to the navigation bar
barButtonItem.title = NSLocalizedString(@"Master", @"Master");
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
// Store references to the button and popover controller so that we can manually open the view using a custome swipe gesture
self.masterPopoverButton = barButtonItem;
self.masterPopoverController = popoverController;
}
Finally, I handle the swipe:
- (void)handleRightSwipe:(UISwipeGestureRecognizer *)recognizer {
// Find the root controller in the stack (this is the one that's also the split view's delegate, and thus has access
// to the pop over controller.
MyDetailViewController *rootController = (MyDetailViewController *)[self.navigationController.viewControllers objectAtIndex:0];
if (!rootController.masterPopoverController.popoverVisible) {
[rootController.masterPopoverController presentPopoverFromBarButtonItem:rootController.masterPopoverButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
This slides in the master view controller. I was concerned that this would display the controller as a traditional popover (with arrows etc), but it actually does the right thing (at least it does under iOS 7 - I haven't tested earlier versions).
Notice that you'll need to create this gesture for each view that you push onto the navigation controller's stack. In my case it's always the same view, so that simplifies things. In other cases it might be a good idea to create a subclass of UIViewController that creates this gesture and handles it, and then use that as a super class for any controllers that are pushed on...