user6120934
user6120934

Reputation:

Calling function when user taps anywhere on screen

In my app I have a small menu I made which is basically a UIView with two button on it. The menu opens when the user taps a button and closes also when the user taps the same button. I'd like the menu to close when the user taps anywhere outside of the menu UIView.

The menu:

I'd like this menu to be closed.

Upvotes: 3

Views: 1853

Answers (5)

ribilynn
ribilynn

Reputation: 543

I'm not sure the code below will work in your case, just a advice.

class ViewController: UIViewController {

  var closeMenuGesture: UITapGestureRecognizer!

  override func viewDidLoad() {
    super.viewDidLoad()

    closeMenuGesture = UITapGestureRecognizer(target: self, action: #selector(closeMenu))
    closeMenuGesture.delegate = self

    // or closeMenuGesture.isEnable = false
  }

  @IBAction func openMenu() {
    view.addGestureRecognizer(closeMenuGesture)
    // or closeMenuGesture.isEnabled = true
  }

  @IBAction func closeMenu() {
    view.removeGestureRecognizer(closeMenuGesture)
    // or closeMenuGesture.isEnabled = false
  }

}

extension ViewController: UIGestureRecognizerDelegate {
  func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    return touch.view === self.view // only valid outside menu UIView
  }
}

And I never be in this situation so not sure making enable/disable closeMenuGesture is enough to ensure other controls work normally, or to add/remove closeMenuGesture is more insured.

Upvotes: 0

Ahmad F
Ahmad F

Reputation: 31645

There are several solutions to your case:

1- Implementing touchesBegan(_:with:) method in your ViewController:

Tells this object that one or more new touches occurred in a view or window.

Simply, as follows:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    // do something
}


2- Add a UITapGestureRecognizer to the main view of your ViewController:

override func viewDidLoad() {
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(doSomething(_:)))
    view.addGestureRecognizer(tapGesture)
}

func doSomething(_ sender: UITapGestureRecognizer) {
    print("do something")
}

Or -of course- you could implement the selector without the parameter:

override func viewDidLoad() {
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(doSomething))
    view.addGestureRecognizer(tapGesture)
}

func doSomething() {
    print("do something")
}


3- You could also follow Mohammad Bashir Sidani's answer.

I would suggest to make sure add the appropriate constraints to your button whether it has been added programmatically or by storyboard.

Upvotes: 0

You can use basically touches began function

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("TAPPED SOMEWHERE ON VIEW")
}

Upvotes: 0

Divyesh Gondaliya
Divyesh Gondaliya

Reputation: 904

You can also apply this easy way

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tapBlurButton(_:)))
    self.view.addGestureRecognizer(tapGesture)


        func tapBlurButton(_ sender: UITapGestureRecognizer) {
            if //checkmenuopen
            {
                closemenuhere
            }
        }

Upvotes: 2

Mohamad Bachir Sidani
Mohamad Bachir Sidani

Reputation: 2099

For that when you show the small menu, add below it a invisible button (UIColor.clear) with the entire screen as a frame. And it's action is to dismiss the menu of yours.

Make sure when you dismiss the small menu to dismiss thus button as well.

Hope this helps!

Upvotes: 1

Related Questions