SwiftUI中ForEach用自定义View报错:Type '_' has no member 'id'
解决SwiftUI ForEach中使用自定义视图出现「Type '_' has no member 'id'」的问题
嗨,我来帮你搞定这个头疼的问题!你遇到的这个错误其实是个误导性提示——根本不是id的问题,而是Swift在类型推断上卡壳了,咱们一步步拆解:
问题根源
你用的是元组数组,虽然每个元组都有id字段,但当你在ForEach的闭包里返回CustomView时,Swift没办法顺利推断这个闭包的返回类型,反而把锅甩给了元组的id,抛出了那个奇怪的错误。而改用Text时,Text的类型非常明确,Swift能轻松推断,所以编译毫无压力。
解决方案
这里有两种靠谱的解决办法,按需选择:
方案1:明确指定ForEach闭包的返回类型
直接告诉Swift闭包要返回CustomView,帮它理清类型:
ForEach(showTargets, id: \.id) { item -> CustomView in CustomView(x: item.x, y: item.y, f: {}) }
这样Swift就不会在类型推断上绕弯路,自然就不会报错了。
方案2:用自定义结构体替代元组(推荐的最佳实践)
元组在SwiftUI的复杂场景下经常出类型推断问题,换成符合Identifiable协议的结构体是更规范的做法:
首先定义结构体:
struct Target: Identifiable { let id: Int var state: Bool let x: CGFloat let y: CGFloat }
然后更新你的数组:
@State private var showTargets = [ Target(id: 1, state: false, x: 109.28, y: 109.28), Target(id: 2, state: false, x: 683, y: 109.28), Target(id: 3, state: false, x: 1256.72, y: 109.28) ]
最后简化ForEach的写法(因为Identifiable已经提供了id):
ForEach(showTargets) { item in CustomView(x: item.x, y: item.y, f: {}) }
这种方式不仅解决了当前的错误,还让代码结构更清晰,后续维护也更方便。
额外小优化
你还可以给CustomView的闭包参数加个默认值,这样调用时不用每次都写f: {}:
struct CustomView : View { // ... 其他属性保持不变 internal var f: ()->() = {} // 这里加默认值 // ... 剩下的代码不变 }
之后调用就可以简化成CustomView(x: item.x, y: item.y),更清爽。
内容的提问来源于stack exchange,提问作者krjw
相关产品推荐
相关产品推荐

