Search code examples
iosswiftnsnotificationcenterswift-extensions

iOS: return value from NSNotificationCenter in an extension (swift)


In my extension I put the control for the keyboard notification in this way

protocol KeyboardSpaceProtocol {
    func addObservers()
    func removeObservers()
    func keyboardWillShow(notification:NSNotification) -> CGFloat
}

extension UIView: KeyboardSpaceProtocol {

    func addObservers() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow), name: UIKeyboardWillShowNotification, object: nil)
    }

    func removeObservers() {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    func keyboardWillShow(notification:NSNotification) -> CGFloat {
        let userInfo:NSDictionary = notification.userInfo!
        let keyboardFrame:NSValue = userInfo.valueForKey(UIKeyboardFrameEndUserInfoKey) as! NSValue
        let keyboardRectangle = keyboardFrame.CGRectValue()
        return keyboardRectangle.height
    }
}

now I want update a CGFloat value (keyboardheight) in my UIView class... how can I in my view controller? I don't know when the keyboard go out and how to update my value. Any suggestions?


Solution

  • You can use objc_associatedObject to add properties at run time.

    My example uses UIViewController instead of UIView just because it seems more logical to me.

    import Foundation
    import UIKit
    import ObjectiveC
    
    protocol KeyboardSpaceProtocol {
        func addObservers()
        func removeObservers()
        func keyboardWillShow(notification:NSNotification) -> CGFloat
        var keyBoardHeight: CGFloat {get set}
    }
    
    private var keyBoardKey: UInt8 = 0
    extension  UIViewController: KeyboardSpaceProtocol {
    
        var keyBoardHeight: CGFloat {
            get {
                return objc_getAssociatedObject(self, &keyBoardKey) as! CGFloat
            }
            set { objc_setAssociatedObject(self, &keyBoardKey, newValue,  objc_AssociationPolicy(rawValue: 0)!) }
        }
    
        func addObservers() {
            NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(UIViewController.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil)
        }
    
        func removeObservers() {
            NSNotificationCenter.defaultCenter().removeObserver(self)
        }
    
        func keyboardWillShow(notification:NSNotification) -> CGFloat {
            let userInfo:NSDictionary = notification.userInfo!
            let keyboardFrame:NSValue = userInfo.valueForKey(UIKeyboardFrameEndUserInfoKey) as! NSValue
            let keyboardRectangle = keyboardFrame.CGRectValue()
    
            var selfAsProtocol = self as KeyboardSpaceProtocol
            selfAsProtocol.keyBoardHeight = keyboardRectangle.height
    
            return keyboardRectangle.height
        }
    }