我创建了一个扩展协议(protocol)来“弹出”任何采用它的 View 。当调用 show 并显示 View 时,将在通知中心添加一个检测键盘将显示的观察者。当 View 被关闭时,该观察者应该从默认的通知中心中删除。
不幸的是,这并没有发生。我认为在这种情况下“ self ”不是观察者。我考虑将“addobserver”中返回的观察者保存到变量中,但我不知道如何在协议(protocol)内部进行操作。任何建议将非常感激。这是我的代码:
protocol PopUpProtocol {
func show()
func dismiss()
var dialogHeight:CGFloat {get}
var backgroundView:UIView {get}
var dialogView:UIView {get set}
}
extension PopUpProtocol where Self:UIView{
func show(){
NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillShow, object: nil, queue: nil) {_ in
self.keyboardWillShow()
}
self.backgroundView.alpha = 0
self.dialogView.frame = CGRect(x: 0, y: self.frame.height , width: self.frame.width, height: self.dialogHeight)
UIApplication.shared.delegate?.window??.rootViewController?.view.addSubview(self)
UIView.animate(withDuration: 0.33, animations: {
self.backgroundView.alpha = 0.66
self.dialogView.frame = CGRect(x: 0, y: self.frame.height-self.dialogHeight , width: self.frame.width, height: self.dialogHeight)
})
}
func dismiss(){
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
UIView.animate(withDuration: 0.33, animations: {
self.backgroundView.alpha = 0
self.dialogView.frame = CGRect(x: 0, y: self.frame.height , width: self.frame.width, height: self.dialogHeight)
}, completion: { (completed) in
self.removeFromSuperview()
})
}
func keyboardWillShow()
{
print("Keyboard will come up")
}
}
最佳答案
好吧,虽然我无法完全解释细节,但我找到了解决方案。我能够拯救观察者。观察到的结果被存储为关联对象:
var KeyboardShowObserverObjectKey: UInt8 = 1
extension PopUpProtocol where Self:UIView{
var keyboardShowObserverObject: NSObjectProtocol? {
get {
return objc_getAssociatedObject(self, &KeyboardShowObserverObjectKey) as? NSObjectProtocol
}
set {
objc_setAssociatedObject(self, &KeyboardShowObserverObjectKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
当我添加观察者时,我然后设置 keyBoardShowObserverObject:
keyboardShowObserverObject = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillShow, object: nil, queue: nil) { (notification) in
self.keyboardWillShow()
}
当我想删除观察者时,我运行这个函数:
private func removeKeyboardObservers() {
if let keyboardShowObserverObject = keyboardShowObserverObject {
NotificationCenter.default.removeObserver(keyboardShowObserverObject)
}
keyboardShowObserverObject = nil
}
此外,我需要将我的协议(protocol)声明为类绑定(bind):
protocol PopUpProtocol : class {
希望这能帮助任何遇到同样问题的人。
关于ios - 无法删除协议(protocol)扩展内的NotificationCenter观察者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47124545/