使用 KVO 观察 swift 中的 view.center 以获得 ios 返回 NSPoint?

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

这是代码

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

输出为:

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

不知道为什么NSclass会出现在iOS中。如何正确观察视图。center/frame/transform using KVO with swift?

由于 KVO 是 Objective-C 运行时的一部分,更改字典是 NSDictionary,而不是本机 Swift 字典。一个 NSDictionary 只能容纳 Objective-C 个对象(这就是为什么在 Swift 中它变成了 [String:AnyObject],而不是 [String:Any]),并且 CGPoint 不是 Objective-C 对象。所以 KVO 必须将 CGPoint 包装在一个对象中。

NSValue 是一个通用的 Objective-C class 用于包装非对象,当观察到的 属性 的类型不是对象类型时,KVO 使用它。 NSValue 是一个“class 集群”,这意味着它定义了一个接口,并且可能有专门的非 public 子 class 实现该接口。在这种情况下,您会看到其中一个子 class 的名称:NSConcreteValue.

您可以通过请求 CGPointValue 属性:

NSValue 中获取 CGPoint
guard let newCenter = change["new"]?.CGPointValue else {
    return
}

打印更改字典时看到NSPoint的原因是历史的偶然。 NSPoint 类型早于 CGPoint,但现在是 OS X 上 CGPoint 的别名(在 Foundation/NSGeometry.h 中定义),并且不存在于全部在 iOS。但是,打印 NSPoint/CGPoint 的代码并未更改为使用新名称(可能是为了向后兼容),并且在 OS X 和 [=42= 上使用相同的代码].