我在 ViewController 上呈现一个 UIView,其中包含一个覆盖整个视图控制器的表视图。我想在点击 UIView 外部时关闭 UIView,但没有找到任何有助于解决问题的方法。这就是我想要做的,它应该可以工作,但即使未呈现 UIView,它也不会注册触摸。有人处理过类似问题吗
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch? = touches.first
if touch?.view != fullSessionView {
fullSessionView?.removeFromSuperview()
}
}
您需要使用要添加的视图的目标和操作来初始化 UITapGestureRecognizer,如下所示:
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
}
首先,我会尝试看看是否有任何内置的演示样式适合您。但是您必须将视图嵌入视图控制器中。
如果您想坚持使用
UIView
,您可以尝试将 UIView
显示在覆盖整个屏幕的透明背景 UIView
之上,并将 UIGestureRecognizer
附加到透明背景。
点击背景会触发回调(通过委托、关闭等),然后删除您的视图。
您应该始终致电
super
,如下所示:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) /// always call the super
但无论如何,你想看看
fullSessionView
是否包含触摸。因此,您可能想要检查触摸发生位置的location,而不是检查触摸发生位置的视图。像这样的东西:
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()
}
}
100% 工作良好
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)
}