我有一个带有按钮的视图控制器,该按钮具有以下操作。
@IBAction func sourceButton(_ sender: Any) {
let menu = sourceMenu()
menu.openMenu()
}
源菜单类是带有以下代码的NSObject类。
class sourceMenu: NSObject {
let blackView = UIView()
public func openMenu(){
if let window = UIApplication.shared.windows.filter({ $0.isKeyWindow }).first {
blackView.frame = window.frame
blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dismissMenu)))
window.addSubview(blackView)
UIView.animate(withDuration: 0.5) {
self.blackView.alpha = 1
}
}
}
@objc public func dismissMenu(){
UIView.animate(withDuration: 0.5) {
self.blackView.alpha = 0
}
}
}
当我点击视图控制器时,未调用功能dismissMenu。有任何想法吗? 谢谢。
答案 0 :(得分:3)
问题实际上是因为对象仅存在于功能块中,所以它正在从内存中释放。函数执行完毕后,您的内存将被清除。您需要在呈现的UIViewController
中创建一个实例,以便arc
使其保持活动状态,因为视图控制器将对其进行引用。您应该像这样声明一个属性。
class ViewController: UIViewController {
let menu = sourceMenu()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func tapAction(_ sender: Any) {
menu.openMenu()
}
}
此外,您只需执行UIApplication.shared.keyWindow
还有什么原因要在窗口上显示而不是使用视图控制器?如果这是每个控制器都应该能够显示的内容,为什么不进行扩展呢?我会避免从窗口显示视图,因为这可能会导致隐藏的问题。
答案 1 :(得分:0)
我曾经遇到过这个问题。我为自己找到的解决方案强烈参考了UITapGestureRecognizer
。因此,您应该做的是:
// Define a gesture variable in class
class sourceMenu: NSObject {
var gestureRecognizer: UITapGestureRecognizer
}
// Use the variable in `openMenu` function
gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissMenu))
blackView.addGestureRecognizer(gestureRecognizer)
}
希望这会有所帮助。