SwiftUI - onTapGesture 中绑定变量的比较(切换网格中行的选择)

问题描述 投票:0回答:1

我可以使用

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
    }
}

(失败:)

编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解为不同的子表达式

swiftui swiftui-foreach swiftui-ontapgesture identifiable
1个回答
0
投票

错误“编译器无法在合理的时间内对该表达式进行类型检查”是您经常看到的错误,当缺少括号、存在拼写错误、或者您尝试访问不存在的属性时,或者还有一些其他的小错误,大多数编译器都能够毫无困难地发现。但 Xcode 不行。

当我尝试你的失败案例时,该错误实际上更有帮助:

运算符函数“==”要求“ContentView.RowItem”符合“Equatable”

解决该问题后,错误将更改为:

'?'后面必须跟有调用、成员查找或下标

因此解决方法是删除

?
。在 Swift 中,您可以将可选值与非可选值进行比较,如果可选值实际上不为零,则它会自动解包。顺便说一句,在 Swift 中你也不需要用括号括住表达式:

.onTapGesture {
    if selectedRow == row {
        selectedRow = nil
    } else {
        selectedRow = row
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.