Reputation: 1543
I'm presenting a UIView over my ViewController which contains a table view that covers the whole view controller. I want to dismiss the UIView when tapping outside of the UIView, but have not found anything that helps the cause. This is what I'm trying to do, and it should work but it's not registering touches even if the UIView is not presented. Anyone dealt with a similar issue?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch? = touches.first
if touch?.view != fullSessionView {
fullSessionView?.removeFromSuperview()
}
}
Upvotes: 1
Views: 2961
Reputation: 500
100% Working Good
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(hideView))
tapGesture.cancelsTouchesInView = false
self.view.addGestureRecognizer(tapGesture)
self.view.backgroundColor = .clear
DispatchQueue.main.asyncAfter(deadline: .now() + 0.18) {
self.view.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.3111622432)
}
}
@objc func hideView() {
self.view.backgroundColor = .clear
self.dismiss(animated: true)
}
Upvotes: -1
Reputation: 1410
You need to initialize UITapGestureRecognizer with a target and action to your view to be added, like so:
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
myView.addGestureRecognizer(tap)
Then, you should implement the handler, which will be called each time when a tap event occurs:
@objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
self.removefromSuperview() // this will remove added view from parent view
}
Upvotes: 2
Reputation: 898
First, I'd try to see if any of the built-in presentation styles could work for you. But you'd have to embed your view in a view controller.
If you want to stick with a UIView
you could try presenting your UIView
on top of a transparent background UIView
that covers the whole screen and attaching a UIGestureRecognizer
to the transparent background.
Tapping the background would trigger a call back (via delegate, closure, etc) that would then remove your view.
Upvotes: 1
Reputation: 30228
You should always call super
, like this:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) /// always call the super
But anyway, you want to see if fullSessionView
contains the touch. So instead of checking the view where the touch happened, you probably want to check the location of where the touch happened. Something like this:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
let touch = touches.first
guard let location = touch?.location(in: fullSessionView) else { return }
if !fullSessionView.frame.contains(location) {
/// tapped outside fullSessionView
fullSessionView?.removeFromSuperview()
}
}
Upvotes: 0