SwiftUI List更新后内部ProgressView消失问题咨询
SwiftUI List底部ProgressView新增内容后消失的原因与解决方法
问题原因
你遇到的问题核心在于SwiftUI的视图身份识别机制和.onAppear的触发逻辑冲突:
- 当滚动到ProgressView时,
.onAppear触发加载新数据,数据添加后List会重新渲染所有子视图 - 由于ProgressView没有绑定稳定的身份标识(id),List在更新时无法正确复用这个视图实例,而是会尝试重建它
- 加上
.onAppear已经触发过,新重建的ProgressView会出现状态异常,表现为进度指示器消失,但单元格和标签还保留
解决方法
要解决这个问题,需要做两件事:
- 给ProgressView添加稳定的身份标识,让List能正确识别并复用它
- 添加加载状态控制,避免重复触发加载逻辑(防止多次调用接口)
修正后的代码
struct ContentView: View { @State var items: [String] = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"] @State private var isLoading = false // 新增加载状态控制 var body: some View { List { ForEach(items, id: \.self) { item in Text(item) .frame(height: 100) } ProgressView { Text("Loading") } .frame(maxWidth: .greatestFiniteMagnitude, alignment: .center) .id("loading-footer") // 给ProgressView添加固定id .onAppear(perform: endOfListReached) .disabled(isLoading) // 加载中禁用触发 } } func endOfListReached() { guard !isLoading else { return } // 避免重复加载 isLoading = true DispatchQueue.main.asyncAfter(deadline: .now() + 2) { items.append("Item \(items.count + 1)") isLoading = false // 加载完成恢复状态 } } }
补充说明
- 添加
.id("loading-footer")后,List在更新时会识别到这是同一个视图,不会重建导致进度指示器消失 - 加载状态
isLoading能防止用户快速滚动时多次触发加载逻辑,避免重复请求服务器
内容的提问来源于stack exchange,提问作者Thofreym
相关产品推荐
相关产品推荐

