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

SwiftUI List点击下载时ProgressView全行显示问题求助

问题原因

你当前使用了一个全局的progress变量,所有列表行的ProgressView都绑定到这个变量上。当任意一个下载任务更新进度时,这个全局变量的值会改变,导致所有行的进度条同步显示相同的进度。

解决方案

需要为每一个书籍条目维护独立的下载进度,而不是使用全局变量。这里提供两种可行的实现方式:

方式一:修改Book模型添加进度属性

如果可以修改Book结构体的定义,直接给它添加一个下载进度属性:

struct Book {
    let bookId: Int // 假设原有属性
    let name: String // 假设原有属性
    // 添加进度属性,默认值0.0
    var downloadProgress: Double = 0.0
}

然后调整列表代码,绑定对应书籍的进度:

List {
    ForEach($books) { $book in // 使用绑定方式访问单个Book
        VStack {
            Text(book.name)
                .font(.system(size: 22))
                .listRowSeparator(.hidden)
            
            Button(NSLocalizedString("Download", comment: "")) {
                let downloadAudio = DownloadAudio()
                downloadAudio.downloadBookId(Int32(book.bookId), 
                                             testamentId: Int32(self.testamentId), 
                                             forLanguage: self.item.language)
                { _, progress, error in
                    // 更新当前书籍的进度
                    book.downloadProgress = progress
                    print(progress)
                }
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            
            // 绑定到当前书籍的进度属性
            ProgressView(value: book.downloadProgress, total: 1.0)
        }
    }
    .listRowSeparator(.hidden)
}

方式二:使用字典存储独立进度(不修改原模型)

如果无法修改Book的原始定义,可以用一个字典来存储每个书籍ID对应的下载进度:

// 在视图中添加这个状态变量
@State private var downloadProgresses: [Int: Double] = [:]

// 列表代码调整:
List {
    ForEach(0..<self.books.count, id: \.self) { index in
        let thisBook = self.books[index]
        // 获取当前书籍的进度,默认0.0
        let currentProgress = self.downloadProgresses[thisBook.bookId] ?? 0.0
        
        VStack {
            Text(thisBook.name)
                .font(.system(size: 22))
                .listRowSeparator(.hidden)
            
            Button(NSLocalizedString("Download", comment: "")) {
                let downloadAudio = DownloadAudio()
                downloadAudio.downloadBookId(Int32(thisBook.bookId), 
                                             testamentId: Int32(self.testamentId), 
                                             forLanguage: self.item.language)
                { _, progress, error in
                    // 更新字典中对应书籍ID的进度
                    self.downloadProgresses[thisBook.bookId] = progress
                    print(progress)
                }
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            
            // 绑定到当前书籍的进度值
            ProgressView(value: currentProgress, total: 1.0)
        }
    }
    .listRowSeparator(.hidden)
}
额外说明
  • 两种方式的核心都是让每个列表行的ProgressView绑定到对应书籍的独立进度值,而非全局变量。
  • 如果下载任务可能被取消或重置,可以在需要时将对应书籍的进度重置为0.0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:16:16