【发布时间】:2022-08-14 05:05:13
【问题描述】:
我有一个带有以下代码的 UIViewController。我想知道肖像效果的值何时更改(在控制中心)。我试过AVCaptureDevice.isPortraitEffectEnabled 和.portraitEffectEnabled,都得到相同的结果:observeValue() 永远不会被调用。我已经验证该值本身确实发生了变化,并且文档声明该成员支持 KVO。
我错过了什么?
为了测试这一点,我通过调用AVCaptureDevice.showSystemUserInterface(.videoEffects) 并打开/关闭它来切换portaitEffectEnabled 的值,并期望KVO 触发。
@objc class EventSettingsCaptureViewController : UIViewController, ... {
required init(...) {
super.init(nibName: nil, bundle: nil)
if #available(iOS 15.0, *) {
AVCaptureDevice.self.addObserver(self, forKeyPath: \"portraitEffectEnabled\", options: [.new], context: nil)
}
}
deinit {
if #available(iOS 15.0, *) {
AVCaptureDevice.self.removeObserver(self, forKeyPath: \"portraitEffectEnabled\", context: nil)
}
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// Breakpoint set here: never hits
if keyPath == \"portraitEffectEnabled\" {
guard let object = object as? AVCaptureDevice.Type else { return }
if #available(iOS 15.0, *) {
WLog(\"isPortraitEffectEnabled changed: \\(object.isPortraitEffectEnabled)\")
}
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
-
这是行不通的,因为
AVCaptureDevice本身没有portraitEffectSupported属性。实例AVCaptureDevice做,因为它是一个实例属性。 developer.apple.com/documentation/avfoundation/… -
顺便说一句,您始终可以使用
class_copyPropertyList再次检查您要观察的属性是否确实存在于该对象上。您可以从中初始化一个不安全的缓冲区指针,然后对其进行映射以获取所有属性的名称,以查看您想要的是否存在 -
请注意,没有“Swift KVO”之类的东西。 KVO 是 Cocoa / Objective-C 的一个特性。
observeValue方法包裹Cocoa KVO,但它本身不做任何事情。 Swift 观察值的方式是使用 setter 观察者、Combine 和 Published 等。 -
呃,谢谢@Alexander - 不敢相信我错过了这个。如果您将其写为答案,我会接受它作为答案吗?
标签: swift avfoundation key-value-observing