SwiftUI Set游戏出现ForEach仅支持常量数据报错,卡片形状数量异常变化怎么解决?
解决方案
问题根源
- 你代码中
CardView内使用的ForEach(0..<card.numberOfShapes.rawValue)写法默认将传入的整数范围视为常量静态数据,SwiftUI不会主动监听该范围的动态变化 - 当LazyVGrid滚动复用卡片视图、或新增卡片触发全局布局重绘时,系统不会重新计算形状数量范围,就会触发count不匹配报错,同时出现卡片形状数量异常变化的问题
修复步骤
- 修改
CardView中的ForEach写法,添加显式id参数:
// 替换原有的ForEach代码 ForEach(0..<card.numberOfShapes.rawValue, id: \.self) { index in cardShape().frame(height: geometry.size.height/6) }
添加id: \.self后,SwiftUI会将该范围识别为动态数据源,每次视图刷新时都会重新校验范围长度,对应更新渲染的形状数量。
- 在主视图调用
CardView的位置添加唯一标识,避免LazyVGrid复用视图时残留旧状态:
CardView(card: card) .padding(4) .id(card.id) // 新增该行,使用卡片自身的唯一id作为视图标识 .onTapGesture { game.choose(card) }
添加.id(card.id)后,只要卡片发生变化,SwiftUI会完整重建对应CardView,不会复用之前卡片的视图缓存,从根源避免滚动时形状数量异常跳转的问题。
效果验证
修改完成后,点击新增卡片、滚动网格两个场景下都不会再触发该报错,卡片形状数量会和底层模型的numberOfShapes属性完全一致。
内容的提问来源于stack exchange,提问作者Amanda
相关产品推荐
相关产品推荐

