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

如何实现带分区的LazyVGrid?滚动卡顿与头部固定失效求助

解决LazyVGrid分区网格的滚动卡顿与头部固定问题

问题根源

你当前代码把LazyVGrid嵌套在了ScrollView中,这会直接破坏LazyVGrid的懒加载机制——原本LazyVGrid只会渲染当前可见区域的内容,但外层套ScrollView后,系统会一次性加载所有网格内容,长列表场景下必然出现卡顿。同时这种嵌套结构也会干扰pinnedViews的头部固定逻辑,导致分区头无法正常固定。

修复方案

  1. 移除外层ScrollView
    LazyVGrid本身自带滚动能力,不需要额外嵌套ScrollView,直接保留LazyVGrid作为根视图即可,这样能恢复懒加载优化,大幅提升滚动流畅度。

  2. 优化数据传递方式
    尽量避免用environmentObject传递ListItemViewModel,直接通过参数传递更高效,还能减少环境依赖带来的不必要重绘。

  3. 确保数据模型的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:42:19