Xcode 11 Playground中的SwiftUI状态更新

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

我无法通过标准的Google搜索找到任何内容,但是是否有任何原因导致ContentView无法通过ObservableObject更新?感觉好像我丢失了一些东西,但我不太确定该怎么办。

import SwiftUI
import PlaygroundSupport

let start = Date()
let seconds = 10.0 * 60.0

func timeRemaining(minutes: Int, seconds: Int) -> String {
    return "\(minutes) minutes \(seconds) seconds"
}

class ViewData : ObservableObject {
    @Published var timeRemaining: String = "Loading..."
}

// View

struct ContentView: View {
    @ObservedObject var viewData: ViewData = ViewData()

    var body: some View {
        VStack {
            Text(viewData.timeRemaining)
        }
    }
}


let contentView = ContentView()
let viewData = contentView.viewData
let hosting = UIHostingController(rootView: contentView)


// Timer

let timer = DispatchSource.makeTimerSource()
timer.schedule(deadline: .now(), repeating: .seconds(1))
timer.setEventHandler {
    let diff = -start.timeIntervalSinceNow
    let remaining = seconds - diff
    let mins = Int(remaining / 60.0)
    let secs = 59 - Int(remaining.remainder(dividingBy: 60.0))
    let timeRemaning = timeRemaining(minutes: mins, seconds: secs)
    viewData.timeRemaining = timeRemaning
    print(timeRemaning)
}
timer.resume()

DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
    timer.cancel()
    PlaygroundPage.current.finishExecution()
}

PlaygroundPage.current.setLiveView(contentView)
PlaygroundPage.current.needsIndefiniteExecution = true

ios swiftui grand-central-dispatch swift-playground xcode11
1个回答
1
投票

原因是基于GCD的计时器在自己的队列上工作,所以这里是解决方法-视图模型必须在主队列,UI队列上进行更新,如下所示

DispatchQueue.main.async {
    viewData.timeRemaining = timeRemaning
}
© www.soinside.com 2019 - 2024. All rights reserved.