问题描述
我试图在我的iOS应用程序的最前面的窗口中添加(背景)蒙版视图.在该蒙版视图上,我想添加一个UITapGestureRecognizer来关闭蒙版视图.最终,我想在中间显示一个弹出窗口(即,我的蒙版视图是该弹出窗口的褪色背景),但现在我只是很难让我的背景像预期的那样消散.
代码如下:我得到最前面的窗口.我创建背景视图并添加Alpha.然后添加我的手势识别器,将其添加到窗口中并添加约束.
但是我的点击手势目标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秒).
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
占用的内存,因为我的代码不再引用它.
I'm trying to add a (background) mask view to the front most window in my iOS app. On that mask view I want to add a UITapGestureRecognizer that will dismiss the mask view. Ultimately, I want to display a popup in the middle (i.e. my mask view is a faded background for the popup), but for now I'm just having trouble getting my background to dismiss as expected.
The code looks like this: I get the front most window. I create the background view and add alpha. Then I add my gesture recognizer, add it to the window and add constraints.
However my tap gesture target didTapOnMaskView()
never gets triggered.
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()
}
** EDIT **After running some more diagnostics, I've noticed that if I add a three-second-delayed block of code to the end of my createMaskView()
that brings the maskView to the front, the gesture works for the first 3.1 seconds until that block of code is executed. Note that if that code block is not there, the gesture recognizer doesn't work at all (not even 3.1 seconds).
As it turns out, not maintaining a reference to the View that contains my maskView was the issue. In the ViewController that creates this View I changed my showPopUp()
function as follows:
// 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
}
Perhaps someone could shed some light on why this is occurring. I suspect that ARC is freeing up the memory that my UITapGestureRecognizer
is occupying because my code no longer references it.
这篇关于TapGestureRecognizer的最前端UIView没有收到触摸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!