SwiftUI Bug:ScrollView内LazyVGrid缓慢滚动时按钮标签异常
SwiftUI LazyVGrid 布局Bug(iOS 15/16)
这是一个在iOS 15、iOS 16系列多个版本真机和模拟器上均能复现的SwiftUI Bug,以下是详细信息:
复现代码
import SwiftUI struct Item: Identifiable { let id: UUID let name: String } struct BugView: View { @State private var showGrid = false let items: [Item] = [ .init(id: UUID(), name: "Addition"), .init(id: UUID(), name: "Subtraction"), .init(id: UUID(), name: "Multiplication"), .init(id: UUID(), name: "Division"), .init(id: UUID(), name: "Times Tables"), .init(id: UUID(), name: "Division Tables"), .init(id: UUID(), name: "Positive and negative numbers"), .init(id: UUID(), name: "Fractions"), .init(id: UUID(), name: "Add Fractions"), .init(id: UUID(), name: "Subtract Fractions"), .init(id: UUID(), name: "Multiply Fractions"), .init(id: UUID(), name: "Divide Fractions"), .init(id: UUID(), name: "Fractional Amount"), .init(id: UUID(), name: "Simplify Fractions"), .init(id: UUID(), name: "Convert to Fractions"), .init(id: UUID(), name: "Decimals"), .init(id: UUID(), name: "Add Decimals"), .init(id: UUID(), name: "Subtract Decimals"), .init(id: UUID(), name: "Multiply Decimals"), .init(id: UUID(), name: "Divide Decimals"), .init(id: UUID(), name: "Round Decimals"), .init(id: UUID(), name: "Convert to Decimals"), .init(id: UUID(), name: "Percentages"), .init(id: UUID(), name: "Percentages of Amount"), .init(id: UUID(), name: "Convert to Percentages"), .init(id: UUID(), name: "Exponents"), .init(id: UUID(), name: "Roots"), .init(id: UUID(), name: "Money"), .init(id: UUID(), name: "Add Money"), .init(id: UUID(), name: "Subtract Money"), .init(id: UUID(), name: "Multiply Money"), .init(id: UUID(), name: "Divide Money"), .init(id: UUID(), name: "Percentages of Money"), .init(id: UUID(), name: "Worksheets"), .init(id: UUID(), name: "Addition Worksheets"), .init(id: UUID(), name: "Multiplication Worksheets") ] var body: some View { if showGrid { ScrollView(.vertical) { LazyVGrid(columns: [GridItem(.adaptive(minimum: 160), spacing: 16, alignment: .top)], spacing: 16) { ForEach(items) { item in Button { } label: { Text(verbatim: item.name) .padding(48) } .buttonStyle(.plain) } } .padding() } } else { Button { showGrid = true } label: { Text(verbatim: "Bug") } } } } @main struct BugApp: App { var body: some Scene { WindowGroup { BugView() } } }
Bug表现
- 触发条件:通过@State变量切换到LazyVGrid视图后,缓慢滚动时间歇性出现
- 症状:最后两个列表项无法显示/完成布局
- 触发范围:仅当LazyVGrid内部嵌套Button或NavigationLink时出现,直接在ForEach中放置标签内容无此问题
- 特殊表现:问题发生时,点击对应的NavigationLink,未显示的项会在跳转前突然出现
- 排除场景:若@State变量
showGrid初始设为true(无视图切换操作),该问题不会出现
已尝试无效的规避方案
- 调整LazyVGrid的columns、spacing等参数
- 添加
fixedSize修饰符 - 修改按钮样式
- 为视图添加id标识
- 移除内边距
- 封装标签视图
推测原因
这是布局与ScrollView更新不及时导致的Bug,目前未找到相关官方文档或已知问题记录。使用.onTapGesture替代Button可规避,但不符合需求。
Bug演示

恳请各位提供解决方案或规避方法,谢谢!
内容的提问来源于stack exchange,提问作者rdor
相关产品推荐
相关产品推荐

