SwiftUI 观察计算属性的变化

问题描述 投票:0回答:1

我的

currentTime
类中有以下计算属性 (
Observable
),我想在 SwiftUI 视图中观察它。问题是属性的更改不会发布,因为它不依赖于存储的属性。我之前一直使用
Combine
publishers来解决这个问题,但我想知道在iOS 17引入的新观察框架中是否有更好的方法来解决这个问题?

   @available(iOS 17.0, *)
   @Observable
    class VideoPlayerVM {
    private(set) public var player: AVPlayer = AVPlayer()


    var currentTime:CMTime {
        let time = self.player?.currentItem?.currentTime()

        if time.isValid {
           return time
        }

        return .invalid
    }

  }
ios swiftui avfoundation observableobject observation
1个回答
0
投票

无论您以前使用什么组合出版商也应该与

@Observable
一起使用。您只需
sink
该发布者并将其值分配给
@Observable
类中的存储属性。

也就是说,如果您想观察

AVPlayer
的当前时间,我不确定为什么您首先要使用组合发布器。有一个专门的方法,
addPeriodicTimeObserver
,可以让你定期观察当前时间。

你可以这样使用它:

@Observable
@MainActor
class VideoPlayerVM {
    private(set) public var player: AVPlayer = AVPlayer()
    
    
    var currentTime: CMTime = .zero
    private var observation: Any?
    
    func startObservingCurrentTime() {
        guard observation == nil else { return }
        observation = player.addPeriodicTimeObserver(
            forInterval: .init(
                seconds: 0.5,
                preferredTimescale: CMTimeScale(NSEC_PER_SEC)
            ),
            queue: nil
        ) { time in
            MainActor.assumeIsolated {
                self.currentTime = time
            }
        }
    }
    
    func stopObservingCurrentTime() {
        if let observation {
            player.removeTimeObserver(observation)
            observation = nil
        }
    }
}

您应该在拥有

stopObservingCurrentTime
的视图的
onDisappear
中调用
VideoPlayerVM

请注意,我在

MainActor.assumeIsolated
的闭包中使用了
addPeriodicTimeObserver
。这是安全的,因为
queue: nil
意味着闭包将在主调度队列上调用,主调度队列是主要参与者的串行执行器。

© www.soinside.com 2019 - 2024. All rights reserved.