如何监听AVPlayerLayer的videoRect变化?KVO实现求助
解决AVPlayerLayer的videoRect KVO监听问题
我来帮你搞定这个KVO监听的麻烦!你当前的代码问题出在找错了监听对象——你直接试图给videoRect这个CGRect值添加观察者,但KVO的规则是要监听AVPlayerLayer对象本身的videoRect属性,而不是属性的具体值。
正确的实现步骤:
添加观察者到AVPlayerLayer对象
把你的监听代码改成这样,针对playerLayer对象,监听videoRect这个属性的变化:playerLayer = AVPlayerLayer(player: player!) // 正确的KVO添加方式:监听playerLayer的videoRect属性 playerLayer?.addObserver(self, forKeyPath: "videoRect", options: [.old, .new], context: nil)实现KVO回调方法处理变化
你需要在当前类中重写observeValue(forKeyPath:of:change:context:)方法,用来接收videoRect的变化通知,然后在这里处理你的图片对齐逻辑:override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { // 先判断是不是我们关心的videoRect属性变化 guard keyPath == "videoRect", let playerLayer = object as? AVPlayerLayer else { // 不是的话交给父类处理 super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) return } // 获取变化后的videoRect,执行你的图片对齐操作 let updatedVideoRect = playerLayer.videoRect // 这里调用你的对齐逻辑方法 alignImageToVideoRect(updatedVideoRect) }记得移除观察者(避免内存泄漏)
在当前类的销毁方法中移除观察者,防止内存泄漏:deinit { playerLayer?.removeObserver(self, forKeyPath: "videoRect") }
为什么之前的代码不行?
videoRect是AVPlayerLayer的一个属性,它的类型是CGRect,这是一个结构体,不属于NSObject子类,所以不能直接给它添加KVO观察者。KVO只能作用于继承自NSObject的对象,监听的是对象的属性名称(字符串形式)。
这样修改后,你就能监听到videoRect的变化,实时调整图片的位置,实现和视频画面的对齐了。
内容的提问来源于stack exchange,提问作者Chewie The Chorkie
相关产品推荐
相关产品推荐

