SKView 上的 KVO 未被调用

问题描述

我正在尝试对 SKView 的一个属性执行 KVO,但它不起作用。

我已经用 .frame 尝试过它,它的作用就像一个魅力,那么为什么不在 .window 上呢?

澄清一下,我在 SwiftUI 应用程序中使用 SpriteView,我试图获取视图的边界。 我所追求的是在应用程序启动之前获得以下内容;

打印(self.convertPoint(fromView: .zero))。当我在

中使用它时
override func didMove

我会得到 Nan/NaN。然而,Apple Code Level Support 说这是关于使用 SpriteView 和获取视图的边界。

您收到 NaN 的原因是您正在调用这些方法 在 SwiftUI 实际呈现底层 SKView 之前, 这是一个您无法看到的事件,也无法调用 发生时编码。

然而,当这个事件确实发生时,SKScene 的 view 属性将 将它的窗口从 nil 设置为 UIWindow。因此,您可以使用 KVO观察window属性什么时候改变,然后让你的 一旦有一个非 nil 窗口就调用 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)

以上似乎没有做任何事情。所以我有点卡住了,任何帮助将不胜感激。

解决方法

答案(可能)..

我无法读取 UIView 的 '.window' 属性,因此我开始寻找另一个可观察的属性,该属性会在 UIWindow 为 != nil 时立即更改。我想我已经在 SKScene.view.frame 中找到了它。我不完全确定这是一个 100% 好的答案,但它有效。

class Observer: NSObject {
    dynamic var kvoToken: NSKeyValueObservation?
    
    func observe(object: SKScene )  {
        kvoToken = object.observe(\.view?.frame,options: [ .new] ) { (object,change) in

        guard let value = change.newValue else { return }
        print("New value is: \(value)")
        print ("CONVERTING",object.convertPoint(fromView: .zero) )
        
      }
    }
    
  deinit {
    kvoToken?.invalidate()
  }
}

override func didMove(to view: SKView) {
    
    viewer = view.scene

    observe.observe(object: viewer )

}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...