如何实现带分区的LazyVGrid?滚动卡顿与头部固定失效求助
解决LazyVGrid分区网格的滚动卡顿与头部固定问题
问题根源
你当前代码把LazyVGrid嵌套在了ScrollView中,这会直接破坏LazyVGrid的懒加载机制——原本LazyVGrid只会渲染当前可见区域的内容,但外层套ScrollView后,系统会一次性加载所有网格内容,长列表场景下必然出现卡顿。同时这种嵌套结构也会干扰pinnedViews的头部固定逻辑,导致分区头无法正常固定。
修复方案
移除外层ScrollView
LazyVGrid本身自带滚动能力,不需要额外嵌套ScrollView,直接保留LazyVGrid作为根视图即可,这样能恢复懒加载优化,大幅提升滚动流畅度。优化数据传递方式
尽量避免用environmentObject传递ListItemViewModel,直接通过参数传递更高效,还能减少环境依赖带来的不必要重绘。确保数据模型的Identifiable实现正确
确认Sections<ListItemViewModel>和ListItemViewModel都正确实现Identifiable协议,保证ForEach的视图复用逻辑正常工作。
修复后的代码示例
struct SectionsGridView: View { let sections: Sections<ListItemViewModel> let columns = [GridItem(.adaptive(minimum: .cellSize))] var body: some View { // 移除外层ScrollView,LazyVGrid自带滚动能力 LazyVGrid(columns: columns, spacing: .gridSpacing, pinnedViews: .sectionHeaders) { ForEach(sections) { section in Section(header: SectionHeaderView(title: section.title?.uppercased() ?? "error")) { ForEach(section) { item in // 直接传参替代environmentObject GridCell(viewModel: item) } } } } } } // 抽离分区头部视图,方便后续样式统一与优化 struct SectionHeaderView: View { let title: String var body: some View { Text(title) .font(.headline) .padding(.vertical, 8) .background(Color(UIColor.systemBackground)) } } private extension CGFloat { static let gridSpacing = 8.0 static let cellSize = 100.0 }
额外优化建议
- 如果
GridCell包含图片加载,使用异步加载框架并设置占位图,避免阻塞UI线程。 - 不要在
GridCell的body中执行复杂计算或数据处理,尽量提前在ListItemViewModel中完成数据准备。 - 给
LazyVGrid加内边距时直接添加,不要嵌套额外容器,减少视图层级。
内容的提问来源于stack exchange,提问作者Jeremy Quinn
相关产品推荐
相关产品推荐

