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

SwiftUI新Alert API无法更新下载进度文本,求解决方案

解决SwiftUI新Alert API无法动态更新下载进度的问题

问题原因

新的.alert(isPresented:actions:message:) API中,message闭包仅在Alert首次呈现时执行一次,后续ViewModel的进度状态变化不会自动触发Alert内容更新。而旧的废弃API会在每次视图重绘时重新生成Alert实例,因此能动态获取最新进度。

解决方案1:确保状态正确发布与追踪

首先保证ViewModel中的进度相关属性通过@Published发布,让SwiftUI能感知变化:

class DownloadViewModel: ObservableObject {
    @Published var downloadProgress: Double = 0.0
    
    // 基于发布的进度计算格式化文本
    var formattedProgressInPercent: String {
        String(format: "%.0f%%", downloadProgress * 100)
    }
    
    func onCancelDownloadTaped() {
        // 取消下载逻辑
    }
}

随后修改Alert调用,利用SwiftUI的状态追踪机制触发内容更新:

.alert("Prepare download", 
       isPresented: $showingAlert, actions: {
           Button("Cancel", role: .cancel) {
               viewModel.onCancelDownloadTaped()
           }
       }, message: {
           Text("The video will be downloaded ... (\(viewModel.formattedProgressInPercent))")
       }
)

由于formattedProgressInPercent依赖@Published的downloadProgress,进度变化时会自动触发Text更新。

解决方案2:使用.alert(item:) API(更可靠)

如果上述方法仍无效果,推荐使用基于Identifiable的.alert(item:) API,它会在绑定的item变化时重新构建Alert,确保内容动态更新:

  1. 定义符合Identifiable的Alert数据模型:
struct DownloadAlertItem: Identifiable {
    let id = UUID()
    var progressText: String
    let cancelAction: () -> Void
}
  1. 在ViewModel中添加对应的发布属性与更新方法:
class DownloadViewModel: ObservableObject {
    @Published var downloadProgress: Double = 0.0
    @Published var downloadAlertItem: DownloadAlertItem?
    
    func updateAlert() {
        let progressText = String(format: "%.0f%%", downloadProgress * 100)
        downloadAlertItem = DownloadAlertItem(
            progressText: progressText,
            cancelAction: { [weak self] in
                self?.onCancelDownloadTaped()
            }
        )
    }
    
    func onCancelDownloadTaped() {
        // 取消下载逻辑
        downloadAlertItem = nil
    }
}
  1. 在视图中使用该API:
.alert(item: $viewModel.downloadAlertItem) { item in
    Alert(
        title: Text("Prepare download"),
        message: Text("The video will be downloaded ... (\(item.progressText))"),
        dismissButton: .cancel(Text("Cancel"), action: item.cancelAction)
    )
}

每次下载进度更新时,调用viewModel.updateAlert()即可刷新Alert中的进度文本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 06:23:34