无法删除协议扩展内的NotificationCenter观察器

时间:2017-11-05 17:38:04

标签: ios iphone swift xcode

我创建了一个扩展协议,以便弹出'任何采用它的观点。调用show并显示视图时,将检测到将显示键盘的观察者添加到NotificationCenter。取消视图时,应从默认的NotificationCenter中删除此观察者。

不幸的是,这种情况并没有发生。我认为自己'在这种情况下不是观察者。我考虑过保存在“addobserver”中返回的观察者。变量,但我不知道如何进行内部协议。非常感谢任何建议。这是我的代码:

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")
    }
}

1 个答案:

答案 0 :(得分:0)

好吧,虽然我无法完全解释细节,但我找到了解决方案。我能够拯救观察者。观察结果存储为关联对象:

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 PopUpProtocol : class {

希望这可以帮助任何挣扎的人。