Frontmost UIView with TapGestureRecognizer not receiving touches

我怕爱的太早我们不能终老 提交于 2019-12-12 01:25:45

问题


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).


回答1:


Since you intend your background view to have the same size as its superview you could try setting the frame size instead of using constraints.

let backgroundView = UIView(frame: applicationKeyWindow.frame)

which has worked for me in the past in a similar situation.

I hope this helps! Have a nice day!




回答2:


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.



来源:https://stackoverflow.com/questions/40144874/frontmost-uiview-with-tapgesturerecognizer-not-receiving-touches

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!