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

SwiftUI:关联Live Activity状态更新列表行的显示与操作

SwiftUI列表与Live Activity状态同步解决方案

核心思路

利用ActivityKit提供的系统API直接查询当前活跃的Live Activity实例,无需自行维护内存或本地存储,通过监听系统通知同步状态,实现列表行的动态UI更新。

具体实现步骤

1. 定义Live Activity属性结构

确保你的ActivityAttributes包含能匹配列表计时器的唯一标识(如timerId),用于后续状态匹配:

import ActivityKit

struct TimerAttributes: ActivityAttributes {
    struct ContentState: Codable, Hashable {
        var remainingTime: TimeInterval // 计时器动态状态
    }
    let timerId: UUID // 与列表计时器ID对应
    let timerName: String
}

2. 列表视图中监听Live Activity状态

在列表视图中维护当前活跃的Activity列表,通过系统通知实时更新:

import SwiftUI
import ActivityKit

struct TimerListView: View {
    let timers: [TimerModel] // 你的计时器数据源
    @State private var activeActivities: [Activity<TimerAttributes>] = []
    
    var body: some View {
        List(timers) { timer in
            HStack {
                Text(timer.name)
                Spacer()
                // 显示已跟踪标记
                if isTracked(timerId: timer.id) {
                    Image(systemName: "pin.fill")
                        .foregroundColor(.orange)
                }
            }
            .swipeActions(edge: .leading) {
                if isTracked(timerId: timer.id) {
                    Button("untrack") {
                        endTracking(timerId: timer.id)
                    }
                    .tint(.red)
                } else {
                    Button("track") {
                        startTracking(timer: timer)
                    }
                    .tint(.green)
                }
            }
        }
        .task {
            // 初始化加载活跃Activity
            activeActivities = Activity<TimerAttributes>.activities
            // 监听Activity状态变化通知
            NotificationCenter.default.addObserver(
                forName: Activity.activityDidChangeNotification,
                object: nil,
                queue: .main
            ) { _ in
                activeActivities = Activity<TimerAttributes>.activities
            }
        }
    }
}

3. 实现状态判断与操作逻辑

添加辅助方法判断计时器是否被跟踪,以及启动/结束Live Activity的逻辑:

extension TimerListView {
    // 判断计时器是否处于跟踪状态
    private func isTracked(timerId: UUID) -> Bool {
        activeActivities.contains { $0.attributes.timerId == timerId }
    }
    
    // 启动Live Activity
    private func startTracking(timer: TimerModel) {
        let attributes = TimerAttributes(timerId: timer.id, timerName: timer.name)
        let initialState = TimerAttributes.ContentState(remainingTime: timer.duration)
        
        do {
            try Activity<TimerAttributes>.request(attributes: attributes, contentState: initialState)
        } catch {
            print("启动跟踪失败: \(error.localizedDescription)")
        }
    }
    
    // 结束Live Activity
    private func endTracking(timerId: UUID) {
        guard let activity = activeActivities.first(where: { $0.attributes.timerId == timerId }) else { return }
        Task {
            await activity.end(dismissalPolicy: .immediate)
            // 立即更新列表状态
            activeActivities.removeAll { $0.id == activity.id }
        }
    }
}

// 示例计时器数据模型
struct TimerModel: Identifiable {
    let id: UUID
    let name: String
    let duration: TimeInterval
}

关键说明

  • 无需手动维护引用:通过Activity<TimerAttributes>.activities直接获取系统中所有活跃的同类型Live Activity,避免内存丢失问题。
  • 实时状态同步:借助Activity.activityDidChangeNotification监听系统通知,在Live Activity启动/结束时自动刷新列表。
  • 精准匹配:通过计时器唯一ID与Activity属性中的timerId关联,确保状态判断准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:57:40