【发布时间】:2021-07-29 10:09:46
【问题描述】:
我正在尝试对 SKView 的一个属性进行 KVO,但它不起作用。
我已经用 .frame 尝试过它,它就像一个魅力,那么为什么不在 .window 上呢?
为了澄清,我在 SwiftUI 应用程序中使用 SpriteView,我试图获取视图的边界。 我所追求的是在应用程序启动之前获得以下内容;
打印 (self.convertPoint(fromView: .zero) )。当我在
中使用它时override func didMove
我会得到 Nan/NaN。然而,Apple Code Level Support 提到了关于使用 SpriteView 和获取视图边界的信息。
您收到 NaN 的原因是您正在调用这些方法 在 SwiftUI 实际呈现底层 SKView 之前, 这是您无法看到且无法调用的事件 发生时的代码。
但是,当此事件发生时,SKScene 的视图属性将 将它的窗口从 nil 设置为 UIWindow。因此,您可以使用 KVO 观察窗口属性何时改变,然后让你的 一旦存在非零窗口,就调用 convertPoint。
到目前为止,我有这个:
override func didMove(to view: SKView) {
observe.observe(object: view )
}
class Observer:SKScene {
var kvoToken: NSKeyValueObservation?
func observe(object: SKView) {
kvoToken = object.observe(\.window , options: [ .new] ) { (object, change) in
guard let value = change.newValue else { return }
print("New value is: \(value)")
print ("NEW", self.convertPoint(fromView: .zero) )
}
}
deinit {
kvoToken?.invalidate()
}
}
我也尝试过像这样添加观察者:
NotificationCenter.default.addObserver(view.window, selector: #selector(test(_:)), name: NSNotification.Name(rawValue: "TestNotification"), object: nil)
上面似乎没有做任何事情。所以我有点卡住了,任何帮助将不胜感激。
【问题讨论】:
-
我把我的问题澄清了一点,也许上下文会有所帮助?
-
哦,我明白了,所以 SwiftUI 先将场景移动到视图,然后再呈现视图。很公平。代码如何不起作用?它什么都不做吗?
-
它没有被调用,它适用于 \.frame 但不适用于 \.windows,我不知道为什么。也许我做错了什么......说真的我不知道。
-
来自this,看来
window不符合KVO 的可能性很大,你根本观察不到。是谁告诉你可以观察到的? -
Apple 提供的代码级支持,是的,我也看到了。这就是我来这里寻求帮助的原因:)
标签: swift sprite-kit key-value-observing skview