You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Live Activity中实现基于Unix时间戳的正计时计数器

iOS Live Activity 实现秒级正计时计数器

当然可以实现,核心是利用系统Text的.timer样式对过去时间的自动计算能力,结合Live Activity的结构即可完成。

实现思路

系统Text(Date, style: .timer)的逻辑是:

  • 传入未来时间:显示倒计时(你已掌握的用法)
  • 传入过去时间:自动显示从该时间到当前时刻的流逝时间,也就是你需要的正计时,格式会自动呈现为00:01、00:02这类分秒样式(时长不足1小时时)

完整代码示例

1. 定义Live Activity属性

import ActivityKit
import WidgetKit
import SwiftUI

struct TimerAttributes: ActivityAttributes {
    struct ContentState: Codable, Hashable {}
    
    // 存储指定的Unix起始时间戳
    let startTimeStamp: TimeInterval
}

2. 实现Live Activity UI

struct TimerLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: TimerAttributes.self) { context in
            // 主屏幕Live Activity界面
            VStack {
                let startTime = Date(timeIntervalSince1970: context.attributes.startTimeStamp)
                Text(startTime, style: .timer)
                    .font(.largeTitle)
                    .monospacedDigit() // 保证数字等宽,显示更整齐
            }
            .padding()
            .background(Color.black)
            .foregroundColor(.white)
            
        } dynamicIsland: { context in
            DynamicIsland {
                // 动态岛展开状态
                DynamicIslandExpandedRegion(.leading) {
                    let startTime = Date(timeIntervalSince1970: context.attributes.startTimeStamp)
                    Text(startTime, style: .timer)
                        .monospacedDigit()
                }
            } compactLeading: {
                // 动态岛紧凑状态左部
                let startTime = Date(timeIntervalSince1970: context.attributes.startTimeStamp)
                Text(startTime, style: .timer)
                    .monospacedDigit()
            } compactTrailing: {
                // 动态岛紧凑状态右部
                Image(systemName: "stopwatch.fill")
            } minimal: {
                // 动态岛最小状态
                Image(systemName: "stopwatch.fill")
            }
            .background(Color.black)
            .foregroundColor(.white)
        }
    }
}

3. 在APP中启动Live Activity

func startTimerLiveActivity(with startTimeStamp: TimeInterval) {
    let attributes = TimerAttributes(startTimeStamp: startTimeStamp)
    let contentState = TimerAttributes.ContentState()
    
    do {
        let activity = try Activity<TimerAttributes>.request(
            attributes: attributes,
            contentState: contentState,
            pushType: nil
        )
        print("Live Activity 已启动,ID:\(activity.id)")
    } catch {
        print("启动Live Activity失败:\(error.localizedDescription)")
    }
}

// 调用示例:比如从当前时间往前推10秒开始计时
// startTimerLiveActivity(with: Date().timeIntervalSince1970 - 10)

注意事项

  • 确保传入的startTimeStamp是秒级Unix时间戳,如果是毫秒级需要先除以1000转换。
  • WidgetKit会自动处理.timer样式的秒级刷新,无需手动配置TimelineProvider,系统会维护UI的实时更新。

内容的提问来源于stack exchange,提问作者raouaoul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 12:30:22