Dismiss modal form sheet view on outside tap iOS 8

前端 未结 3 1650
故里飘歌
故里飘歌 2020-12-14 08:08

I\'ve been trying to dismiss the modal form sheet view on outside tap on iOS 8 with no luck, I\'ve tried this code

UITapGestureRecognizer *recognizer = [[U         


        
相关标签:
3条回答
  • 2020-12-14 08:37

    There are actually two problems in iOS 8. First, the gesture recognition does not begin.

    I solved this by adding the UIGestureRecognizerDelegate protocol and implementing

    -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer
    {
        return YES;
    }
    

    Also, don't forget to register the delegate with

    recognizer.delegate = self;
    

    Now the gesture recognizer should recognize gestures and the target method (handleTapBehind:) will be called.

    Here comes the second problem in iOS 8: locationInView: doesn't seem to take the device orientation into account if nil is passed as a view. Instead, passing the root view works.

    Here's my target code that seems to work for iOS 7.1 and 8.0:

    if (sender.state == UIGestureRecognizerStateEnded) {
        UIView *rootView = self.view.window.rootViewController.view;
        CGPoint location = [sender locationInView:rootView];
        if (![self.view pointInside:[self.view convertPoint:location fromView:rootView] withEvent:nil]) {
            [self dismissViewControllerAnimated:YES completion:^{
                [self.view.window removeGestureRecognizer:sender];
            }];
        }
    }
    
    0 讨论(0)
  • 2020-12-14 08:39

    Swift 3.1 solution that works in both portrait and landscape.

    class TapBehindModalViewController: UIViewController, UIGestureRecognizerDelegate {
        private var tapOutsideRecognizer: UITapGestureRecognizer!
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
    
            if(self.tapOutsideRecognizer == nil) {
                self.tapOutsideRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTapBehind))
                self.tapOutsideRecognizer.numberOfTapsRequired = 1
                self.tapOutsideRecognizer.cancelsTouchesInView = false
                self.tapOutsideRecognizer.delegate = self
                self.view.window?.addGestureRecognizer(self.tapOutsideRecognizer)
            }
        }
    
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
    
            if(self.tapOutsideRecognizer != nil) {
                self.view.window?.removeGestureRecognizer(self.tapOutsideRecognizer)
                self.tapOutsideRecognizer = nil
            }
        }
    
        func close(sender: AnyObject) {
            self.dismiss(animated: true, completion: nil)
        }
    
        // MARK: - Gesture methods to dismiss this with tap outside
        func handleTapBehind(sender: UITapGestureRecognizer) {
            if (sender.state == UIGestureRecognizerState.ended) {
                let location: CGPoint = sender.location(in: self.view)
    
                if (!self.view.point(inside: location, with: nil)) {
                    self.view.window?.removeGestureRecognizer(sender)
                    self.close(sender: sender)
                }
            }
        }
    
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    }
    
    0 讨论(0)
  • 2020-12-14 08:51

    In iOS 8, You can look at using the new UIPresentationController class. It gives you better control over the container around your custom view controller presentation (allowing you to correctly add a gesture recogniser of your own).

    Here is a link to quite a simple tutorial as well: http://dativestudios.com/blog/2014/06/29/presentation-controllers/

    Then add the dimming view tap-to-dismiss:

        UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
        [self.dimmingView addGestureRecognizer:singleFingerTap];
    
    
    - (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
        [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
    }
    
    0 讨论(0)
提交回复
热议问题