为什么SwiftUI的onTapGesture不总是起作用?

23

在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()
        }
    }
}
2个回答

48

这里的矩形是透明的,但手势需要内容不透明。

这里有一个修复方法(在Xcode 11.4 / iOS 13.4上进行了测试)

Rectangle()
    .foregroundColor(self.cellFg[row][column])
    .border(Color.gray, width: 1)
    .contentShape(Rectangle())         // << here !!

.contentShape可以使整个框架独立于透明度而具有点击测试功能。


好的提示。有所帮助。找到了更多关于这个问题的细节 -> https://www.hackingwithswift.com/quick-start/swiftui/how-to-control-the-tappable-area-of-a-view-using-contentshape - app4g
这个问题困扰了我好几个小时:“但是手势需要内容不透明。”非常感谢! - undefined

2
添加一个扩展程序来解决这个问题。
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)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接