By default the UISplitViewController provides a swipe gesture to open the master view in portrait mode.
Unfortunately, this gesture opens the master controller even when manipulating sliders on the detail page! I discovered another question on here where this was marked as a bug reported for iOS 5.1, and yet the problem persists on iOS7...
Is there now a way to suppress this gesture under these circumstances? I realise that I can remove it completely by doing this:
splitViewController.presentsWithGesture = NO;
However it would be nice to allow the gesture and still have usable sliders!
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With