我正在尝试在 macOS 上实现 GridView 项目的单击和双击。第一次单击时,它应该突出显示该项目。第二次单击时,应打开详细信息 View 。
struct MyGridView: View {
var items: [String]
@State var selectedItem: String?
var body: some View {
LazyVGrid(columns: [
GridItem(.adaptive(minimum: 200, maximum: 270))
], alignment: .center, spacing: 8, pinnedViews: []) {
ForEach(items, id: \.self) { item in
Text("Test")
.gesture(TapGesture(count: 2).onEnded {
print("double clicked")
})
.simultaneousGesture(TapGesture().onEnded {
self.selectedItem = item
})
.background(self.selectedItem == item ? Color.red : .blue)
}
}
}
问题
突出显示按预期工作,没有延迟。但由于第一次单击会更新 View ,因此双击的 TapGesture
将被忽略。只有之前选择了该项目,双击才有效,因为不需要再次更新 View 。
我正在关注https://stackoverflow.com/a/59992192/1752496但它不考虑第一次点击后的 View 更新。
最佳答案
据我所知,没有内置函数或类似的东西来理解 singleTap 或 doubleTap 之间的差异,但我们有无限的自由来构建我们想要的东西,我发现这样:
您可以将 tapRecognizer 应用于您想要的任何内容,效果相同!为了展示我刚刚应用于 Circle() 的用例。
import SwiftUI
struct ContentView: View {
var body: some View {
Circle()
.fill(Color.red)
.frame(width: 100, height: 100, alignment: .center)
.tapRecognizer(tapSensitivity: 0.2, singleTapAction: singleTapAction, doubleTapAction: doubleTapAction)
}
func singleTapAction() { print("singleTapAction") }
func doubleTapAction() { print("doubleTapAction") }
}
struct TapRecognizerViewModifier: ViewModifier {
@State private var singleTapIsTaped: Bool = Bool()
var tapSensitivity: Double
var singleTapAction: () -> Void
var doubleTapAction: () -> Void
init(tapSensitivity: Double, singleTapAction: @escaping () -> Void, doubleTapAction: @escaping () -> Void) {
self.tapSensitivity = tapSensitivity
self.singleTapAction = singleTapAction
self.doubleTapAction = doubleTapAction
}
func body(content: Content) -> some View {
return content
.gesture(simultaneouslyGesture)
}
private var singleTapGesture: some Gesture { TapGesture(count: 1).onEnded{
singleTapIsTaped = true
DispatchQueue.main.asyncAfter(deadline: .now() + tapSensitivity) { if singleTapIsTaped { singleTapAction() } }
} }
private var doubleTapGesture: some Gesture { TapGesture(count: 2).onEnded{ singleTapIsTaped = false; doubleTapAction() } }
private var simultaneouslyGesture: some Gesture { singleTapGesture.simultaneously(with: doubleTapGesture) }
}
extension View {
func tapRecognizer(tapSensitivity: Double, singleTapAction: @escaping () -> Void, doubleTapAction: @escaping () -> Void) -> some View {
return self.modifier(TapRecognizerViewModifier(tapSensitivity: tapSensitivity, singleTapAction: singleTapAction, doubleTapAction: doubleTapAction))
}
}
关于swift - 更新 View 时处理单击和双击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66430942/