SwiftUI 计时器未启动

SwiftUI Timer is not starting

我在 Xcode SwiftUI 的三个不同应用程序中尝试了几种不同的 运行 计时器(onRecieve 和 scheduled)方法,但尚未看到计时器在模拟器中工作。为了演示目的,我遵循了以下视频中的说明:

https://www.youtube.com/watch?v=y68YmyTB7JU

我不确定 Xcode 是否有需要修改的设置以在我的笔记本电脑上的模拟器中启用计时器,或者我是否缺少更新版本 [=25] 所需的内容=].不过,截至目前,该视频只有大约 6 个月的历史 post。

提前致谢!

内容视图:

import SwiftUI

struct ContentView: View {
    @ObservedObject var stopWatchManager = StopWatchManager()
    
    var body: some View {
        VStack {
            Text(String(format: "%.1f", stopWatchManager.secondsElapsed))
                .font(.system(size: 50))
                .foregroundColor(.yellow)
                .padding(.top, 200)
                .padding(.bottom, 100)
                .padding(.trailing, 100)
                .padding(.leading, 100)
            
            if stopWatchManager.mode == .stopped{
                Button(action: {self.stopWatchManager.start()}){
                    TimerButton(label: "Start", buttonColor: .green, textColor: .black)
                }
            }
            
            if stopWatchManager.mode == .running{
                Button(action: {self.stopWatchManager.pause()}){
                    TimerButton(label: "Pause", buttonColor: .green, textColor: .black)
                }
            }
            
            if stopWatchManager.mode == .paused{
                Button(action: {self.stopWatchManager.start()}){
                    TimerButton(label: "Start", buttonColor: .green, textColor: .black)
                }
                Button(action: {self.stopWatchManager.stop()}){
                    TimerButton(label: "Stop", buttonColor: .red, textColor: .black)
                }
                .padding(.top, 30)
            }
            
            Spacer()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct TimerButton: View {
    
    let label: String
    let buttonColor: Color
    let textColor: Color
    
    var body: some View {
        Text(label)
            .foregroundColor(textColor)
            .padding(.vertical, 20)
            .padding(.horizontal, 90)
            .background(buttonColor)
            .cornerRadius(10)
    }
}

秒表管理器:

import Foundation
import SwiftUI

class StopWatchManager: ObservableObject{
    
    enum stopWatchMode {
        case running
        case stopped
        case paused
    }
    
    @Published var mode: stopWatchMode = .stopped
    
    @Published var secondsElapsed = 0
    var timer = Timer()
    
    func start() {
        mode = .running
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
            timer in self.secondsElapsed += 1
        }
    }

    func pause() {
        timer.invalidate()
        mode = .paused
    }
        
    func stop() {
        timer.invalidate()
        secondsElapsed = 0
        mode = .stopped
    }
}

这是一个难以识别的偷偷摸摸的错误。

在您的代码中,您已将 elapsedSeconds 定义为:

@Published var secondsElapsed = 0

Swift 进行类型推断以推断 secondsElapsed 是一个 Int 。当您使用 String(format: "%.1f"...) 时,它需要一个 Double (浮点数)并且不会使用 Int.

正确更新

在视频代码中,您会看到 secondsElapsed 定义为:

@Published var secondsElapsed = 0.0

Swift 将其推断为 Double -- 如果您进行该更改,一切都会按预期工作。

PS:您可以考虑将 Timer 与 Combine(例如 Timer.publish)结合使用,以获得更以 SwiftUI 为中心的操作方式事物。参见 the documentation