调用Binding对象的myFunction()报错:无法调用非函数类型值
问题场景
在SwiftUI中使用ForEach时,以下代码触发错误:
ForEach($trip.myFunction(), id: \.id) { $stop in
错误提示:
Cannot call value of non-function type 'Binding<() -> [Binding]>'
对应的Trip模型定义如下:
struct Trip: Codable, Identifiable { let stops: [TripStop]? enum CodingKeys: String, CodingKey { case stops = "stops" } func myFunction() -> [TripStop] { if let stops = stops { return stops.filter({ $0.date == nil }) } return [] } }
疑问:为什么不能通过Binding调用myFunction()?该怎么解决?
问题原因与解决办法
核心原因
$trip是Binding<Trip>类型,它只是对Trip实例的引用包装,本身并不是Trip实例。而myFunction()是定义在Trip值类型上的实例方法,自然没法直接通过Binding调用——Swift会把这种错误调用解析成试图访问Binding内部不存在的函数类型属性,于是抛出了上述提示。
针对性解决办法
情况1:只需要读取过滤后的数据,不需要双向绑定
直接用trip(而非$trip)调用myFunction()即可,因为trip是真正的Trip实例:
ForEach(trip.myFunction(), id: \.id) { stop in // 这里只能读取stop的属性,无法修改绑定 }
情况2:需要对过滤后的元素进行双向绑定
这种情况要分两步调整:
- 先把模型里的
stops改成可变的var,如果要支持响应式更新,让Trip遵循ObservableObject并给stops加上@Published:
struct Trip: Codable, Identifiable, ObservableObject { @Published var stops: [TripStop]? enum CodingKeys: String, CodingKey { case stops = "stops" } func myFunction() -> [TripStop] { stops?.filter({ $0.date == nil }) ?? [] } }
- 在视图中通过索引绑定原数组的元素,因为过滤后的数组是原数组的子集,无法直接绑定,得关联到原数组的对应位置:
ForEach(trip.myFunction(), id: \.id) { stop in if let index = trip.stops?.firstIndex(where: { $0.id == stop.id }) { // 通过索引绑定到原数组元素,支持双向修改 TextField("站点名称", text: $trip.stops![index].name) } }
情况3:不想修改原模型,直接生成过滤后的绑定数组
可以手动构建一个包含Binding<TripStop>的数组,再传给ForEach:
// 先过滤出符合条件的元素,再通过索引创建绑定 let filteredBindings: [Binding<TripStop>] = trip.stops? .enumerated() .filter { $0.element.date == nil } .map { index, _ in $trip.stops![index] } ?? [] ForEach(filteredBindings, id: \.id) { $stop in // 这里可以正常使用$stop进行双向绑定 }
内容的提问来源于stack exchange,提问作者user896541
相关产品推荐
相关产品推荐

