带有 TapGestureRecognizer 的最前面的 UIView 未接收到触摸
Frontmost UIView with TapGestureRecognizer not receiving touches
我正在尝试在我的 iOS 应用中将(背景)遮罩视图添加到最前面 window。在那个掩码视图上,我想添加一个 UITapGestureRecognizer 来关闭掩码视图。最终,我想在中间显示一个弹出窗口(即我的蒙版视图是弹出窗口的褪色背景),但现在我只是无法按预期关闭我的背景。
代码如下所示:我得到最前面的 window。我创建背景视图并添加 alpha。然后我添加我的手势识别器,将其添加到 window 并添加约束。
但是我的点击手势目标 didTapOnMaskView()
从未被触发。
private func createMaskView() {
let applicationKeyWindow = UIApplication.shared.windows.last
backgroundView = UIView()
backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.backgroundColor = UIColor(white: 0, alpha: 0.2)
backgroundDismissGesture = UITapGestureRecognizer(target: self, action: #selector(didTapOnMaskView))
backgroundDismissGesture.numberOfTapsRequired = 1
backgroundDismissGesture.cancelsTouchesInView = false;
backgroundView.addGestureRecognizer(backgroundDismissGesture)
backgroundView.isUserInteractionEnabled = true
backgroundView.alpha = 0.0
UIView.animate(withDuration: 0.4) {
self.backgroundView.alpha = 1.0
}
applicationKeyWindow.addSubview(backgroundView)
let views: [String: UIView] = [ "backgroundView": backgroundView]
var allConstraints = [NSLayoutConstraint]()
let verticalConstraint = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[backgroundView]-0-|", options: [], metrics: nil, views: views)
allConstraints += verticalConstraint
let horizontalConstraint = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[backgroundView]-0-|", options: [], metrics: nil, views: views)
allConstraints += horizontalConstraint
NSLayoutConstraint.activate(allConstraints)
// This is super odd, but the gesture gets triggered until the following code block executes
DispatchQueue.main.asyncAfter(deadline: .now() + 3.1) {
applicationKeyWindow.bringSubview(toFront: self.backgroundView)
}
}
func didTapOnMaskView() {
hide()
}
func show(){
createMaskView()
}
** 编辑 **
在 运行 一些更多的诊断之后,我注意到如果我在我的 createMaskView()
的末尾添加一个三秒延迟的代码块,将 maskView 带到前面,手势适用于执行该代码块前的 3.1 秒。请注意,如果该代码块不存在,则手势识别器根本不起作用(甚至不到 3.1 秒)。
由于您希望背景视图与其父视图具有相同的大小,因此您可以尝试设置框架大小而不是使用约束。
let backgroundView = UIView(frame: applicationKeyWindow.frame)
过去在类似情况下对我有用。
希望对您有所帮助!祝你有美好的一天!
事实证明,没有维护对包含我的 maskView 的视图的引用是问题所在。在创建此视图的 ViewController 中,我更改了我的 showPopUp()
函数,如下所示:
// Stored property on my View Controller class
var myPopupView: UIView?
private func showLMBFormSubmittedPopup(){
let popupView = MyPopupView()
popupView.show()
// Once I added this line, it started working
myPopupView = popupView
}
也许有人可以阐明发生这种情况的原因。我怀疑 ARC 正在释放我的 UITapGestureRecognizer
占用的内存,因为我的代码不再引用它。
我正在尝试在我的 iOS 应用中将(背景)遮罩视图添加到最前面 window。在那个掩码视图上,我想添加一个 UITapGestureRecognizer 来关闭掩码视图。最终,我想在中间显示一个弹出窗口(即我的蒙版视图是弹出窗口的褪色背景),但现在我只是无法按预期关闭我的背景。
代码如下所示:我得到最前面的 window。我创建背景视图并添加 alpha。然后我添加我的手势识别器,将其添加到 window 并添加约束。
但是我的点击手势目标 didTapOnMaskView()
从未被触发。
private func createMaskView() {
let applicationKeyWindow = UIApplication.shared.windows.last
backgroundView = UIView()
backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.backgroundColor = UIColor(white: 0, alpha: 0.2)
backgroundDismissGesture = UITapGestureRecognizer(target: self, action: #selector(didTapOnMaskView))
backgroundDismissGesture.numberOfTapsRequired = 1
backgroundDismissGesture.cancelsTouchesInView = false;
backgroundView.addGestureRecognizer(backgroundDismissGesture)
backgroundView.isUserInteractionEnabled = true
backgroundView.alpha = 0.0
UIView.animate(withDuration: 0.4) {
self.backgroundView.alpha = 1.0
}
applicationKeyWindow.addSubview(backgroundView)
let views: [String: UIView] = [ "backgroundView": backgroundView]
var allConstraints = [NSLayoutConstraint]()
let verticalConstraint = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[backgroundView]-0-|", options: [], metrics: nil, views: views)
allConstraints += verticalConstraint
let horizontalConstraint = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[backgroundView]-0-|", options: [], metrics: nil, views: views)
allConstraints += horizontalConstraint
NSLayoutConstraint.activate(allConstraints)
// This is super odd, but the gesture gets triggered until the following code block executes
DispatchQueue.main.asyncAfter(deadline: .now() + 3.1) {
applicationKeyWindow.bringSubview(toFront: self.backgroundView)
}
}
func didTapOnMaskView() {
hide()
}
func show(){
createMaskView()
}
** 编辑 **
在 运行 一些更多的诊断之后,我注意到如果我在我的 createMaskView()
的末尾添加一个三秒延迟的代码块,将 maskView 带到前面,手势适用于执行该代码块前的 3.1 秒。请注意,如果该代码块不存在,则手势识别器根本不起作用(甚至不到 3.1 秒)。
由于您希望背景视图与其父视图具有相同的大小,因此您可以尝试设置框架大小而不是使用约束。
let backgroundView = UIView(frame: applicationKeyWindow.frame)
过去在类似情况下对我有用。
希望对您有所帮助!祝你有美好的一天!
事实证明,没有维护对包含我的 maskView 的视图的引用是问题所在。在创建此视图的 ViewController 中,我更改了我的 showPopUp()
函数,如下所示:
// Stored property on my View Controller class
var myPopupView: UIView?
private func showLMBFormSubmittedPopup(){
let popupView = MyPopupView()
popupView.show()
// Once I added this line, it started working
myPopupView = popupView
}
也许有人可以阐明发生这种情况的原因。我怀疑 ARC 正在释放我的 UITapGestureRecognizer
占用的内存,因为我的代码不再引用它。