Morty Choi
Morty Choi

Reputation: 2550

Using KVO to observing view.center in swift for ios give back NSPoint?

Here is the code

view.addObserver(self, forKeyPath: "center", options: .New, context: nil)

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    guard let change = change else {
        return
    }

    print(change)

    guard let newCenter = change["new"] else {
        return
    }

    print(newCenter.dynamicType)
}

And the output is :

["new": NSPoint: {50, 50.5}, "kind": 1]
NSConcreteValue

I don't know why NS class will appear in iOS. How to correctly observe view.center/frame/transform using KVO with swift?

Upvotes: 0

Views: 960

Answers (1)

rob mayoff
rob mayoff

Reputation: 385840

Since KVO is part of the Objective-C runtime, the change dictionary is an NSDictionary, not a native Swift dictionary. An NSDictionary can only hold Objective-C objects (which is why, in Swift, it becomes a [String:AnyObject], not a [String:Any]), and CGPoint is not an Objective-C object. So KVO has to wrap the CGPoint in an object.

NSValue is a generic Objective-C class for wrapping non-objects, and KVO uses it when the observed property's type is not an object type. NSValue is a “class cluster”, which means it defines an interface and may have specialized, non-public subclasses that implement the interface. In this case, you're seeing the name of one of those subclasses: NSConcreteValue.

You can get the CGPoint value from the NSValue by asking for its CGPointValue property:

guard let newCenter = change["new"]?.CGPointValue else {
    return
}

The reason you see NSPoint when you print the change dictionary is an accident of history. The NSPoint type is older than CGPoint, but is now an alias for CGPoint on OS X (defined in Foundation/NSGeometry.h), and doesn't exist at all on iOS. However, the code to print NSPoint/CGPoint was not changed to use the new name (probably for backward compatibility) and the same code is used on both OS X and iOS.

Upvotes: 3

Related Questions