Dismiss modal view form sheet controller on outside tap

前端 未结 13 1053
猫巷女王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条回答
  •  孤独总比滥情好
    2020-12-01 06:54

    Based on Bart van Kuik's answer and NavAutoDismiss and other great snippets here.

    class DismissableNavigationController: UINavigationController, UIGestureRecognizerDelegate {
        private var tapOutsideRecognizer: UITapGestureRecognizer!
    
        override func viewDidAppear(animated: Bool) {
            super.viewDidAppear(animated)
    
            if tapOutsideRecognizer == nil {
                tapOutsideRecognizer = UITapGestureRecognizer(target: self, action: #selector(DismissableNavigationController.handleTapBehind))
                tapOutsideRecognizer.numberOfTapsRequired = 1
                tapOutsideRecognizer.cancelsTouchesInView = false
                tapOutsideRecognizer.delegate = self
                view.window?.addGestureRecognizer(tapOutsideRecognizer)
            }
        }
    
        override func viewWillDisappear(animated: Bool) {
            super.viewWillDisappear(animated)
    
            if tapOutsideRecognizer != nil {
                view.window?.removeGestureRecognizer(tapOutsideRecognizer)
                tapOutsideRecognizer = nil
            }
        }
    
        func close(sender: AnyObject) {
            dismissViewControllerAnimated(true, completion: nil)
        }
    
        func handleTapBehind(sender: UITapGestureRecognizer) {
            if sender.state == UIGestureRecognizerState.Ended {
                var location: CGPoint = sender.locationInView(nil)
    
                if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) {
                    location = CGPoint(x: location.y, y: location.x)
                }
    
                if !view.pointInside(view.convertPoint(location, fromView: view.window), withEvent: nil) {
                    view.window?.removeGestureRecognizer(sender)
                    close(sender)
                }
            }
        }
    
        func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    }
    

    Usage:

    let vc = MyViewController()
    let nc = DismissableNavigationController(rootViewController: vc)
    nc.modalPresentationStyle = UIModalPresentationStyle.FormSheet
    presentViewController(nc, animated: true, completion: nil)
    

提交回复
热议问题