在 Mac 上的 Xcode 17 中,我尝试选择 10x10 网格中的单元格。我整理了以下代码,只是为了让自己相信它是有效的。它似乎确实有效,只是在开始给细胞着色之前有一个延迟。它不是一个杀手,但足以让它在开始选择之前通常会错过第一个或两个单元格。一旦开始运行,它就会非常聪明地挑选细胞。这种延迟是我必须忍受的吗?抱歉,我是一名老 Lisp 程序员,试图记住如何编程...感谢您的帮助。
import SwiftUI
let cellSize: CGFloat = 30
struct ContentView: View {
@State var cellColors: [[Color]] = Array(repeating: Array(repeating: .white, count: 10), count: 10)
var body: some View {
VStack {
ZStack() {
Rectangle() //Bounding box for grid
.fill(Color.clear)
.stroke(Color.red, lineWidth: 0)
.frame(width: 10 * cellSize, height: 10 * cellSize)
.coordinateSpace(name: "Grid")
VStack(spacing: 0){
ForEach (0..<10, id: \.self){row in
GridRow(content: {
HStack(spacing: 0){
ForEach (0..<10, id: \.self){column in
Rectangle()
.fill(cellColors[row][column])
.stroke(Color.yellow, lineWidth: 2)
.frame(width: cellSize, height: cellSize)
.onTapGesture {coord in
cellColors[row][column] = .red
print("Tap: \(row), \(column)")
}
}
}
})
}
}
.padding()
.frame(width: 10 * cellSize, height: 10 * cellSize)
.gesture(DragGesture(minimumDistance: 0,
coordinateSpace: .named("Grid"))
.onChanged() { drag in
let cellRow = Int(drag.location.y/cellSize)
let cellColumn = Int(drag.location.x/cellSize)
cellColors[cellRow][cellColumn] = .blue
}
.onEnded() { drag in
print("DragEnd: \(drag.location)")
}
)
}
}
}
}
我单击一个单元格并开始拖动。我预计(实际上希望)它会将单元格着色为蓝色并继续直到我停止。在开始给细胞着色之前几乎总是有短暂的延迟。如果我将光标放在单元格中并非常缓慢地拖动,它通常会开始使用正确的单元格着色。这种延迟是否来自我可以控制的来源?或者事情就是这样? 我尝试尽我所能清理代码(这是一个陡峭的学习曲线!)。
DragGesture
正在与您添加到矩形中的 onTapGesture
“战斗”。发生延迟是因为拖动手势正在“等待”点击手势是否触发。
点击手势仅在您触摸的时间少于 X 毫秒时才会触发。如果您触摸的时间过长,则不会触发点击手势。拖动手势基本上是等待X毫秒,之后它知道你没有“点击”,然后它才会调用它的
onChange
。
解决此问题的一种方法是将拖动手势转变为高优先级手势,这样它就不会等待点击手势。但现在点击手势永远不会触发,因此您还需要将拖动手势的
minimumDistance
设置为非零,以便当用户不移动手指时可以触发点击手势。
.highPriorityGesture(DragGesture(minimumDistance: 1, coordinateSpace: .named("Grid"))
我没有在真实设备上测试
1
的这个值。 1
适用于我用鼠标点击的模拟器,不确定用手指实际点击是否有效。尝试找到一个大于<人们点击时手指通常移动的距离>。