swift - 更新 View 时处理单击和双击

标签 swift macos swiftui

我正在尝试在 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))
  
    }

}

enter image description here

关于swift - 更新 View 时处理单击和双击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66430942/

相关文章:

ios - 在核心数据中获取 NSManagedObject 上下文时找不到 objectID 错误

ios - 用相同的测试测试两个目标

xcode - 任何与UIKit的 “touch down”等效的SwiftUI按钮,即在您的手指触摸时激活按钮?

ios - 在 UIView 中从 UIViewController 快速调用组件

swift - 是否有与 Swift 3's ' 数据类型等效的 writeToFile?

node.js - 创建新项目时 MEAN Stack yomeanjs 返回错误

ios - 在 swiftUI 中是否可以使用按钮在屏幕上添加新 View ?

swift - 如何在预览中设置环境对象

macos - pkgbuild OSX,降级时强制安装失败

java - C++ JNI想要安装Mac Legacy JRE6