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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:19:56