我可以使用
onTapGesture
选择行项目,如果再次点击则取消选择。
问题是为什么下面的代码可以工作,但最后显示的代码却不能?
@Binding var selectedRow: RowItem?
var body: some View {
ForEach(modelData.rows) { row in
LazyVGrid(columns: columns) {
Text("text")
Text("text")
}
.onTapGesture {
if (selectedRow?.id == row.id) {
selectedRow = nil
} else {
selectedRow = row
}
}
}
}
其中
modelData.rows
是 [RowItem]
,
RowItem 是:struct RowItem: Identifiable
并定义了一个等式函数:
static func == (lhs: RowItem, rhs: RowItem) -> Bool {
rhs.id == lhs.id
}
为什么必须使用
id
,而下面的却不起作用?
.onTapGesture {
if (selectedRow? == row) {
selectedRow = nil
} else {
selectedRow = row
}
}
(失败:)
编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解为不同的子表达式
错误“编译器无法在合理的时间内对该表达式进行类型检查”是您经常看到的错误,当缺少括号、存在拼写错误、或者您尝试访问不存在的属性时,或者还有一些其他的小错误,大多数编译器都能够毫无困难地发现。但 Xcode 不行。
当我尝试你的失败案例时,该错误实际上更有帮助:
运算符函数“==”要求“ContentView.RowItem”符合“Equatable”
解决该问题后,错误将更改为:
'?'后面必须跟有调用、成员查找或下标
因此解决方法是删除
?
。在 Swift 中,您可以将可选值与非可选值进行比较,如果可选值实际上不为零,则它会自动解包。顺便说一句,在 Swift 中你也不需要用括号括住表达式:
.onTapGesture {
if selectedRow == row {
selectedRow = nil
} else {
selectedRow = row
}
}