Reputation:
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:
Upvotes: 3
Views: 1853
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
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
Reputation: 35
You can use basically touches began function
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("TAPPED SOMEWHERE ON VIEW")
}
Upvotes: 0
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
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