0

我想添加一個(背景)蒙板視圖到我的iOS應用中最前面的窗口。在該遮罩視圖上,我想添加一個將關閉遮罩視圖的UITapGestureRecognizer。最終,我想在中間顯示一個彈出窗口(即我的遮罩視圖是彈出窗口的褪色背景),但現在我只是無法按預期方式解除背景。TapGestureRecognizer最前端的UIView沒有收到觸摸

代碼如下所示:我得到最前面的窗口。我創建背景視圖並添加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秒)。

回答

0

事實證明,不保留對包含我的maskView的視圖的引用是問題。在創建此視圖的視圖控制器我改變了我的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佔用的內存,因爲我的代碼不再引用它。

0

由於您打算使您的背景視圖與其超級視圖具有相同的大小,因此您可以嘗試設置框架大小而不是使用約束。

let backgroundView = UIView(frame: applicationKeyWindow.frame)

這爲我在類似的情況曾在過去。

我希望這有助於!祝你今天愉快!

+0

不幸的是,我仍然無法接收觸摸。似乎沒有改變任何東西... – toddg

+0

我知道這似乎很奇怪,但你可以嘗試在應用手勢識別器之前激活約束。 – KGJ

+0

我用UIScreen窗口邊界'UIView(frame:UIScreen.main.bounds)' – KGJ