I am presenting a modal view controller as a form sheet and dismissing it when the cancel button, which is a bar button item, is clicked. I need to dismiss it when I tap on outside of that view. Please help me with a reference. Note: my modal view controller is presented with a navigation controller.
@cli_hlt, @Bill Brasky thanks for your answer. I need to dismiss it when tap occurs outside of the modal view which is a form sheet. I am pasting my code below.
-(void)gridView:(AQGridView *)gridView didSelectItemAtIndex:(NSUInteger)index { if(adminMode) { CHEditEmployeeViewController *editVC = [[CHEditEmployeeViewController alloc] initWithNibName:@"CHEditEmployeeViewController" bundle:nil]; editVC.delegate = self; editVC.pickedEmployee = employee; editVC.edit = TRUE; editVC.delegate = self; UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:editVC]; navigationController.modalPresentationStyle = UIModalPresentationFormSheet; [self presentModalViewController:navigationController animated:YES]; return; } //the above code is from the view controller which presents the modal view. Please look at the below code too which is from my modal view controller. Please guide me in a proper way. -(void)tapGestureRecognizer { UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapBehind:)]; [recognizer setNumberOfTapsRequired:1]; recognizer.cancelsTouchesInView = NO; //So the user can still interact with controls in the modal view [self.view addGestureRecognizer:recognizer]; } - (void)handleTapBehind:(UITapGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateEnded) { CGPoint location = [sender locationInView:nil]; //Passing nil gives us coordinates in the window //Then we convert the tap's location into the local view's coordinate system, and test to see if it's in or outside. If outside, dismiss the view. if (![self.view pointInside:[self.view convertPoint:location fromView:self.view.window] withEvent:nil]) { [self dismissModalViewControllerAnimated:YES]; [self.view.window removeGestureRecognizer:sender]; } } }
According to the View Controller Programming guide for iPhone OS, this is incorrect when it comes to dismissing modal view controllers you should use delegation. So before presenting your modal view make yourself the delegate and then call the delegate from the modal view controller to dismiss.
I know this is an old question but this IS possible, despite of what the "right" answer says. Since this was the first result when I was looking for this I decided to elaborate:
This is how you do it:
You need to add a property to the View Controller from where you want to present modally, in my case "tapBehindGesture".
then in viewDidAppear
if(!tapBehindGesture) { tapBehindGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapBehindDetected:)]; [tapBehindGesture setNumberOfTapsRequired:1]; [tapBehindGesture setCancelsTouchesInView:NO]; //So the user can still interact with controls in the modal view } [self.view.window addGestureRecognizer:tapBehindGesture];
And Here is the implementation for tapBehindDetected
- (void)tapBehindDetected:(UITapGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateEnded) { //(edited) not working for ios8 above //CGPoint location = [sender locationInView:nil]; //Passing nil gives us coordinates in the window CGPoint location = [sender locationInView: self.presentingViewController.view]; //Convert tap location into the local view's coordinate system. If outside, dismiss the view. if (![self.presentedViewController.view pointInside:[self.presentedViewController.view convertPoint:location fromView:self.view.window] withEvent:nil]) { if(self.presentedViewController) { [self dismissViewControllerAnimated:YES completion:nil]; } } } }
Just remember to remove tapBehindGesture
from view.window
on viewWillDisappear
to avoid triggering handleTapBehind in an unallocated object.
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