为什么 SwiftUI onTapGesture 总是不起作用
Why doesn't SwiftUI onTapGesture always work
SWiftUI 中的 onTapGesture 无法可靠地工作。此示例显示了问题,即有时当您点击一个单元格时,背景会按应有的方式变为灰色,而另一次相邻的单元格发生变化,而在其他时候什么也没有发生。有什么想法吗?
struct ContentView: View {
@State var cellFg: [[Color]] = [
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear]
]
var body: some View {
VStack {
Spacer()
ForEach(0..<9) { row in
HStack {
Spacer()
ForEach(0..<9) { column in
Rectangle()
.foregroundColor(cellFg[row][column])
.border(Color.gray, width: 1)
// When you tap, it sometimes works, sometimes selects
// an adjacent cell and sometimes does nothing
.onTapGesture {
print("Row \(row) - Column\(column)")
cellFg[row][column] = .gray
}
}
Spacer()
}
}
Spacer()
}
}
}
这里的矩形是透明的,但是手势要求内容是不透明的。
这是一个修复程序(使用 Xcode 11.4 / iOS 13.4 测试)
Rectangle()
.foregroundColor(self.cellFg[row][column])
.border(Color.gray, width: 1)
.contentShape(Rectangle()) // << here !!
.contentShape
使整个帧的命中测试独立于透明度。
添加一个扩展来解决这个问题
private struct ExpandAreaTap: ViewModifier {
func body(content: Content) -> some View {
ZStack {
Rectangle()
.foregroundColor(Color.white)
.contentShape(Rectangle())
content
}
}
}
extension View {
func expandTap(tap: @escaping () -> ()) -> some View {
self.modifier(ExpandAreaTap()).onTapGesture(perform: tap)
}
}
SWiftUI 中的 onTapGesture 无法可靠地工作。此示例显示了问题,即有时当您点击一个单元格时,背景会按应有的方式变为灰色,而另一次相邻的单元格发生变化,而在其他时候什么也没有发生。有什么想法吗?
struct ContentView: View {
@State var cellFg: [[Color]] = [
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear],
[.clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear, .clear]
]
var body: some View {
VStack {
Spacer()
ForEach(0..<9) { row in
HStack {
Spacer()
ForEach(0..<9) { column in
Rectangle()
.foregroundColor(cellFg[row][column])
.border(Color.gray, width: 1)
// When you tap, it sometimes works, sometimes selects
// an adjacent cell and sometimes does nothing
.onTapGesture {
print("Row \(row) - Column\(column)")
cellFg[row][column] = .gray
}
}
Spacer()
}
}
Spacer()
}
}
}
这里的矩形是透明的,但是手势要求内容是不透明的。
这是一个修复程序(使用 Xcode 11.4 / iOS 13.4 测试)
Rectangle()
.foregroundColor(self.cellFg[row][column])
.border(Color.gray, width: 1)
.contentShape(Rectangle()) // << here !!
.contentShape
使整个帧的命中测试独立于透明度。
添加一个扩展来解决这个问题
private struct ExpandAreaTap: ViewModifier {
func body(content: Content) -> some View {
ZStack {
Rectangle()
.foregroundColor(Color.white)
.contentShape(Rectangle())
content
}
}
}
extension View {
func expandTap(tap: @escaping () -> ()) -> some View {
self.modifier(ExpandAreaTap()).onTapGesture(perform: tap)
}
}