Search code examples
iosswiftuiviewuikituigesturerecognizer

How to dismiss UIView on tap Swift4


I have a UIView that is showed every time I press a button in another view

@IBOutlet weak var view1: UIView!
@IBOutlet weak var view2: UIView! 

@IBAction func showView(_ sender: Any) {
    view2.isHidden = false
}

What I want is to add a tap gesture that allows me to hide view2 every time I tap outside of the view and, since those views are draggable, I want the second view not to be tappable when hidden ( so that if I touch under my view I don't risk to move it. This is what I tried:

  1. var gesture : UITapGestureRecognizer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(closeView), name: NSNotification.Name("CloseView"), object: nil)
    
    
        gesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.closeView))
    }
    @objc func closeView() {
        if view2.isHidden == false {
            view2.isUserInteractionEnabled = true
            view2.isHidden = false
            self.view.removeGestureRecognizer(gesture!)
        } else {
            view2.isHidden = true
            view2.isUserInteractionEnabled = true
            self.view.addGestureRecognizer(gesture!)
        }
    
    }
    
  2. let closeTapGesture = UITapGestureRecognizer(target: view, action: #selector(getter: view2.isHidden)
        view.addGestureRecognizer(closeTapGesture)
    

None of this work, how can I do?


Solution

  • You need to check if you actually tapped outside of view2:

        var gesture : UITapGestureRecognizer?
    
        override func viewDidLoad() {
            super.viewDidLoad()
            NotificationCenter.default.addObserver(self,
                                                   selector: #selector(closeView), name: NSNotification.Name("CloseView"), object: nil)
    
    
            let gesture = UITapGestureRecognizer(target: self, action: #selector(closeView(_:)))
            view.addGestureRecognizer(gesture)
            self.gesture = gesture
        }
    
        @objc private func closeView(_ tapGestureRecognizer: UITapGestureRecognizer) {
            let location = tapGestureRecognizer.location(in: view2)
            guard view2.isHidden == false,
                  !view2.bounds.contains(location) else {  //We need to have tapped outside of view 2
                return
            }
            view2.isHidden = true
        }