首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何制作一个计时器来显示SwiftUI中经过了多少时间?

如何制作一个计时器来显示SwiftUI中经过了多少时间?
EN

Stack Overflow用户
提问于 2021-01-15 23:53:11
回答 2查看 137关注 0票数 0

我正尝试在视图顶部添加一个计时器,以显示该视图已打开多长时间。

到目前为止,我得到的是:

代码语言:javascript
运行
复制
@State var isTimerRunning = false
@State private var startTime =  Date()
@State private var timerString = "0:0"
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

Text(self.timerString)
    .font(Font.system(.largeTitle, design: .monospaced))
    .onReceive(timer) { _ in
        if self.isTimerRunning {
            timerString = String(format: "%.2f", (Date().timeIntervalSince( self.startTime)))
            }
        }
     .onAppear() {
         if !isTimerRunning {
             timerString = "0:0"
             startTime = Date()
         }
         isTimerRunning.toggle()
     }

然而,它以"1.32434234234234“的形式显示毫秒和秒,而我希望它以"12:43”的形式显示秒和分钟。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-16 00:21:28

为此,您可以使用TimeInterval的扩展。通过更改formatter.unitsStyle (.positional将显示00:00:00,而.abbreviated将显示0h 0m 0s)和formatter.zeroFormattingBehavior变量,您可以很好地定制字符串。

extension found here的演职人员。

代码语言:javascript
运行
复制
extension TimeInterval {
    func format(using units: NSCalendar.Unit) -> String {
        let formatter = DateComponentsFormatter()
        formatter.allowedUnits = units
        formatter.unitsStyle = .positional
        formatter.zeroFormattingBehavior = .pad
        return formatter.string(from: self) ?? ""
    }
}

struct TimerPlayground: View {
    @State var isTimerRunning = false
    @State private var startTime =  Date()
    @State var interval = TimeInterval()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        Text(interval.format(using: [.hour, .minute, .second]))
            .font(Font.system(.largeTitle, design: .monospaced))
            .onReceive(timer) { _ in
                if self.isTimerRunning {
                    interval = Date().timeIntervalSince(startTime)
                }
            }
             .onAppear() {
                 if !isTimerRunning {
                     startTime = Date()
                 }
                 isTimerRunning.toggle()
             }
    }
}

struct TimerPlayground_Previews: PreviewProvider {
    static var previews: some View {
        TimerPlayground()
    }
}

根据@Duncan C的评论,这里是一个更新版本,它只创建一次格式化程序(本地),以获得更好的性能。

代码语言:javascript
运行
复制
struct TimerPlayground: View {
    @State var isTimerRunning = false
    @State private var startTime =  Date()
    @State var interval = TimeInterval()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    @State var formatter: DateComponentsFormatter = {
        let formatter = DateComponentsFormatter()
        formatter.allowedUnits = [.hour, .minute, .second]
        formatter.unitsStyle = .abbreviated
        formatter.zeroFormattingBehavior = .pad
        return formatter
    }()
    
    var body: some View {
        Text(formatter.string(from: interval) ?? "")
            .font(Font.system(.largeTitle, design: .monospaced))
            .onReceive(timer) { _ in
                if self.isTimerRunning {
                    interval = Date().timeIntervalSince(startTime)
                }
            }
             .onAppear() {
                 if !isTimerRunning {
                     startTime = Date()
                 }
                 isTimerRunning.toggle()
             }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2021-01-16 00:09:02

使用dateComponents获取开始时间和当前时间之间的差值。

代码语言:javascript
运行
复制
extension Date {
    func passedTime(from date: Date) -> String {
        let difference = Calendar.current.dateComponents([.minute, .second], from: date, to: self)
        
        let strMin = String(format: "%02d", difference.minute ?? 00)
        let strSec = String(format: "%02d", difference.second ?? 00)
        
        return "\(strMin):\(strSec)"
    }
}

在视图中

代码语言:javascript
运行
复制
struct ContentView: View {
    @State private var isTimerRunning = false
    @State private var startTime =  Date()
    @State private var timerString = "00:00"
    
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        Text(self.timerString)
            .font(Font.system(.largeTitle, design: .monospaced))
            .onReceive(timer) { _ in
                if self.isTimerRunning {
                    timerString = Date().passedTime(from: startTime)
                }
            }
            .onAppear() {
                if !isTimerRunning {
                    timerString = "0:0"
                    startTime = Date()
                }
                isTimerRunning.toggle()
            }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65739258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档