Dismiss modal view form sheet controller on outside tap

前端 未结 13 1041
猫巷女王i
猫巷女王i 2020-12-01 06:16

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

13条回答
  •  Happy的楠姐
    2020-12-01 06:54

    As far as I can tell none of the answer seem to be working right away in every condition.

    My solution (either inherit from it or paste it in):

    @interface MyViewController () 
    
    @property (strong, nonatomic) UITapGestureRecognizer *tapOutsideRecognizer;
    
    @end
    
    -(void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
        if (!self.tapOutsideRecognizer) {
            self.tapOutsideRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapBehind:)];
            self.tapOutsideRecognizer.numberOfTapsRequired = 1;
            self.tapOutsideRecognizer.cancelsTouchesInView = NO;
            self.tapOutsideRecognizer.delegate = self;
            [self.view.window addGestureRecognizer:self.tapOutsideRecognizer];
        }
    }
    
    -(void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        // to avoid nasty crashes
        if (self.tapOutsideRecognizer) {
            [self.view.window removeGestureRecognizer:self.tapOutsideRecognizer];
            self.tapOutsideRecognizer = nil;
        }
    }
    
    #pragma mark - Actions 
    
    - (IBAction)close:(id)sender
    {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (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])
            {
                // Remove the recognizer first so it's view.window is valid.
                [self.view.window removeGestureRecognizer:sender];
                [self close:sender];
            }
        }
    }
    
    #pragma mark - Gesture Recognizer
    // because of iOS8
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
        return YES;
    }
    

提交回复
热议问题