已更新:错误:类型'_'没有成员'1',为什么?关键路径表达问题?
代码版本4:
struct Timestamp: Identifiable, Hashable {
var id: ID
var name: String = ""
var timeAt: Double = 0
var marked: Bool = false
}
var timestamps: [Timestamp] { return ... }
var body: some View {
...
List {
ForEach(Array(zip(0..., timestamps)), id: \.1.id) { index, timestamp in // error: Type '_' has no member '1'
if !self.showMarkedOnly || timestamp.marked {
self.timestampItemView(timestamp, withIndex: index)
}
}
}
...
}
==========
已更新:我发现了代码版本2的问题,我必须提供ForEach的ID。并更新了代码版本2。
我发现了一种显示索引的优美方法,它避免了self.list [index]。但是我发现某些复杂代码中出现了错误“类型'_'没有成员'1'”。
代码版本3:
var body: some View {
List {
ForEach(Array(zip(0..., list)), id: \.1.id) { index, name in // a error occurs in some complex code: "Type '_' has no member '1'"
HStack {
Text("\(index)")
Spacer()
Text("\(name.name)")
}
.background(Color.gray.opacity(0.001))
.onTapGesture {
self.list.remove(at: index)
}
}
}
}
我显示一个列表,然后删除我点击的项目。它是代码版本1,工作正常。当我使用索引(代码版本2)将索引添加到列表项时,点击后出现“致命错误:索引超出范围”。
代码版本1:
struct Name: Identifiable, Hashable {
var id: String = UUID().uuidString
var name: String
init(_ name: String) { self.name = name }
}
struct TestView: View {
@State private var list: [Name] = [Name("test1"), Name("test2"), Name("test3"), Name("test4"), Name("test5"), Name("test6"), Name("test7"), Name("test8")]
var body: some View {
List {
ForEach(list) { name in
HStack {
Text("\(0)")
Spacer()
Text("\(name.name)")
}
.background(Color.gray.opacity(0.001))
.onTapGesture {
self.list = self.list.filter { $0 != name }
}
}
}
}
}
代码版本2:
struct TestView: View {
@State private var list: [Name] = [Name("test1"), Name("test2"), Name("test3"), Name("test4"), Name("test5"), Name("test6"), Name("test7"), Name("test8")]
var body: some View {
List {
//ForEach(list.indices) { index in
ForEach(list.indices, id: \.self) { index in
HStack {
Text("\(index)")
Spacer()
Text("\(self.list[index].name)")
}
.background(Color.gray.opacity(0.001))
.onTapGesture {
self.list.remove(at: index)
}
}
}
}
}
这是因为indices
不是您的状态,而是数组。因此,您更新了数组,但是@State
实际上不够聪明,无法更新其包装的值的计算或下游属性。如果需要索引,请在ForEach
:
ForEach(0..<list.count, id: \.self) {
// the rest should be ok here
}
@ State是属性包装器,它将强制对其定义的视图重新计算其主体。
根据您的情况,如果您删除索引处的项目,则>>
HStack { Text("\(index)") Spacer() Text("\(self.list[index].name)") } .background(Color.gray.opacity(0.001)) .onTapGesture { self.list.remove(at: index) }
HStack中的文本
Text("\(self.list[index].name)")
崩溃,仅因为list [index]不再存在。
使用中
ForEach(list.indices, id:\.self) { index in ... }
代替
ForEach(list.indices) { index in ... }
将强制SwiftUI重新创建TestView(请参阅ForEach构造函数中的id:\。self)
SwiftUI将使用包装在@State属性包装器中的属性的新值来制作TestView的新副本。
这是因为SwiftUI根据所提供的原始数据重新加载其内容。您可以通过修改