在 swiftUI 中捕获 onLongPressGesture 的 touchDown 位置?

2024-05-06

我正在尝试实现一个自定义上下文菜单,该菜单将在用户触摸的位置长按后出现。我一直无法找到一种方法来捕获 onLongPressGesture 的触地事件的 XY 位置。

这就是我开始的地方

struct ExampleView: View {
    @State var showCustomContextMenu = false
    @State var longPressLocation = CGPoint.zero
    
    var body: some View {
        Rectangle()
            .foregroundColor(Color.green)
            .frame(width: 100.0, height: 100.0)
            .onLongPressGesture {
                print("OnLongPressGesture")
                self.showCustomContextMenu = true
            }
            .overlay(
                Rectangle()
                    .foregroundColor(Color.red)
                    .frame(width: 50.0, height: 50.0)
                    .position(longPressLocation) // <----- this is what I need to capture.
                    .opacity( (showCustomContextMenu) ? 1 : 0 )
        )
    }
}

看了这个问题(以及答案中链接的其他问题)后,我尝试了以下操作。

struct ExampleView: View {
    @State var showCustomContextMenu = false
    @State var longPressLocation = CGPoint.zero
    
    var body: some View {
        ZStack{
            Rectangle()
                .foregroundColor(Color.green)
                .frame(width: 100.0, height: 100.0)
                .onLongPressGesture {
                    print("OnLongPressGesture")
                    self.showCustomContextMenu = true
                }
                .overlay(
                    Rectangle()
                        .foregroundColor(Color.red)
                        .frame(width: 50.0, height: 50.0)
                        .position(longPressLocation)
                        .opacity( (showCustomContextMenu) ? 1 : 0 )
            )
            TapView { point in
                self.longPressLocation = point
                print("Point: \(point)")
            }.background(Color.gray).opacity(0.5)
        }
    }
}

struct TapView: UIViewRepresentable {
    var tappedCallback: ((CGPoint) -> Void)

    func makeUIView(context: UIViewRepresentableContext<TapView>) -> TapView.UIViewType {
        let v = UIView(frame: .zero)
        let gesture = SingleTouchDownGestureRecognizer(target: context.coordinator,
                                                       action: #selector(Coordinator.tapped))
        v.addGestureRecognizer(gesture)
        return v
    }

    class Coordinator: NSObject {
        var tappedCallback: ((CGPoint) -> Void)

        init(tappedCallback: @escaping ((CGPoint) -> Void)) {
            self.tappedCallback = tappedCallback
        }

        @objc func tapped(gesture:UITapGestureRecognizer) {
            self.tappedCallback(gesture.location(in: gesture.view))
        }
    }

    func makeCoordinator() -> TapView.Coordinator {
        return Coordinator(tappedCallback:self.tappedCallback)
    }

    func updateUIView(_ uiView: UIView,
                      context: UIViewRepresentableContext<TapView>) {
    }
}

class SingleTouchDownGestureRecognizer: UIGestureRecognizer {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        if self.state == .possible {
            self.state = .recognized
        }
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        self.state = .failed
    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
        self.state = .failed
    }
}

这几乎可以工作,但是,这给我留下的问题是,由于 Rectangle() 和 TapView() 位于 ZStack 中,具体取决于我将它们放置在代码中的位置either触地位置oronLongPressGesture 但不是两者。

我看过但遇到类似问题的其他问题链接如下

如何在 SwiftUI 中检测点击手势位置? https://stackoverflow.com/questions/56513942/how-to-detect-a-tap-gesture-location-in-swiftui

Swift:长按手势识别器 - 检测轻击和长按 https://stackoverflow.com/questions/28058082/swift-long-press-gesture-recognizer-detect-taps-and-long-press这可能是我正在寻找的,但我不确定如何使其适应 SwiftUI。


这是可能方法的演示。它需要两种手势的组合:长按检测长按和拖动检测位置。

使用 Xcode 12 / iOS 14 进行测试。(在以下系统上可能需要添加self.某些属性的使用)

struct ExampleView: View {
    @State var showCustomContextMenu = false
    @State var longPressLocation = CGPoint.zero

    var body: some View {
        Rectangle()
            .foregroundColor(Color.green)
            .frame(width: 100.0, height: 100.0)
            .onTapGesture { showCustomContextMenu = false } // just for demo
            .gesture(LongPressGesture(minimumDuration: 1).sequenced(before: DragGesture(minimumDistance: 0, coordinateSpace: .local))
                .onEnded { value in
                    switch value {
                        case .second(true, let drag):
                            longPressLocation = drag?.location ?? .zero   // capture location !!
                            showCustomContextMenu = true
                        default:
                            break
                    }
            })
            .overlay(
                Rectangle()
                    .foregroundColor(Color.red)
                    .frame(width: 50.0, height: 50.0)
                    .position(longPressLocation)
                    .opacity( (showCustomContextMenu) ? 1 : 0 )
                    .allowsHitTesting(false)
        )
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 swiftUI 中捕获 onLongPressGesture 的 touchDown 位置? 的相关文章

  • 自定义 UISearchController 动画

    底线问题 如何覆盖取消属于 UISearchController 的 searchBar 的默认动画 标准搜索控制器行为 好的 我正在尝试为附加到 UISearchController 的 UISearchBar 变为活动状态时创建自定义动
  • 推送通知 applicationIconBadgeNumber 在 ios7 中未更新

    我在应用程序委托中使用以下代码来接收远程通知 但当应用程序在后台时 其 applicationIconBadgeNumber 以红色 白色显示在应用程序图标的左上角 不会更新 当推送通知收到时 它会以幻灯片动画出现在屏幕的右上角 通知有效负
  • 在 macOS 中获取用户首选的温度设置

    我正在尝试读取温度单位 摄氏度 华氏度 的用户设置系统首选项 我试图使用 NSLocale 获取此数据 但我找不到任何温度设置的证据 甚至可以读取这些数据吗 Thanks 官方 API 记录在首选项 实用程序 https developer
  • iOS) 照片扩展无法保存更改问题

    我正在制作照片扩展 但是当我尝试保存更改时 点击 完成 按钮 警报消息显示 无法保存更改 发生错误 节省的同时 请稍后再试 这是我的代码finishContentEditingWithCompletionHandler completion
  • RestKit RKObjectMapping Swift 可选

    我有一个名为Activity可以选择有一个coordinate附于其上 import MapKit class Activity NSObject var coordinate CLLocationCoordinate2D class fu
  • 快速 Firebase 在异步任务中返回

    我在 swift 2 中遇到了适用于 iOS 的 Firebase SDK 的问题 我正在尝试将图片设置为从 Firebase 存储下载 当我调用该函数时 它返回 nil 我认为这是因为 Firebase sdk 提供的下载任务是异步的 因
  • iOS:AVPlayer 视频预加载

    我正在使用 AVPlayer 来播放视频 它们的长度很短 2 5秒 它们以随机顺序播放 问题是 当更改视频并开始播放新视频时 设备会滞后很短的时间 但我不希望更改流畅 有没有办法用 AVPlayer 预加载视频 尝试使用AVQueuePla
  • 核心蓝牙框架本质上是异步的吗?

    当我在应用程序中使用 CB 框架时 我没有引入任何并发性或反应性方法 并且一切正常 当我每秒从外设接收超过 100 个样本时 UI 不会被阻止 这是否意味着它被设计为异步工作 我没有找到任何说明它具有异步性质的资源 也没有找到任何在使用核心
  • UITableView 中具有多个部分的搜索控制器

    我有一个 UIViewController 其中有一个 UITableView 在该表视图内我有多个部分 其中有一些项目 我必须在该表视图内使用项目名称进行搜索 我已经在我的视图控制器中声明了这一点 let searchController
  • iPhone 旋转时 CALayer 自动旋转

    我有一个 UIViewController 其中我将 CALayer 子类添加到视图层 self view layer addSublayer myObject backgroundLayer 当我旋转设备时 视图会旋转 但 CALayer
  • 如何使用最新的 FBSDK 在 iOS 应用程序中集成 Facebook,而不重定向 Safari 浏览器

    您好 我正在搜索避免新的 facebooksdk 重定向到 safari 的答案 如何在应用程序内打开 facebook 登录视图 如果它重定向到 safari 可能会在应用程序商店中拒绝 帮助我 提前致谢 昨天我使用以下方式提交我的应用程
  • 导航栏的横向视图问题

    默认导航栏高度为 64 但更改后 其横向导航栏高度的方向更改为 28 我想设置修复所有方向的导航栏大小 您可以添加方向观察者 NotificationCenter default addObserver self selector sele
  • Swift AVCaptureSession 关闭打开按钮错误:当前不支持多个音频/视频 AVCaptureInputs

    我有一个可用的条形码扫描仪代码 当我点击openCamera按钮 第一次一切都很好 当我点击closeCamera按钮 很好 但是如果我再次点击openCamera按钮给出致命错误 代码和错误如下 事实上 是否可以一键切换相机视图 Barc
  • 如何将预编译头文件添加到我的 ios 项目中?

    我希望创建一个预编译头文件 以避免在项目中的每个头文件中包含相同的调试和跟踪库 我创建了一个名为 Prefix pch 的文件 ifdef OBJC import Blah h import Blarg h endif 并将其添加到项目中
  • 检查 NSIndexPath 的行和部分的开关

    我想设置一个 switch 语句来检查值 ifNSIndexPath NSIndexPath是一个类 它由 除其他外 部分和行组成 indexPath row indexPath section 这就是我如何制定 if 语句来同时检查行和部
  • Swift - 集成 GameCenter 以使用排行榜

    我正在用 Swift 制作一个游戏 我希望能够使用 GameCenter 发布用户的分数 以便可以看到所有用户的分数 然而 我花了一天的时间试图弄清楚如何做到这一点 但我没有找到任何有用的说明 我对 iOS 编程和 Swift 还很陌生 关
  • 当状态为 AVKeyValueStatusFailed 时重新加载 AVAsset 中的密钥

    我正在执行以下操作 创建一个新的AVAsset与给定的 URL 该 URL 指向远程 Web 服务器上的视频 尝试加载tracks通过调用属性loadValuesAsynchronouslyForKeys completionHandler
  • 为什么 NSOrderedSet 不继承 NSSet?

    当然 有序集是集合的更具体的情况 那么为什么NSOrderedSet继承自NSObject而不是NSSet 我通过了界面NSSet你是对的 有序集似乎满足里氏替换原则 http en wikipedia org wiki Liskov su
  • iOS 10 和 swift 2.3 中支持的InterfaceOrientations

    我正在使用 Xcode 8 GM 并且有一个旧项目需要更新为 iOS 10 我发现我当前使用 Swift 2 2 版本的应用商店构建在 iOS 10 上运行时不支持所需的界面方向功能 简而言之 当我重写supportedInterfaceO
  • 与桌面浏览器相比,移动浏览器有多强大? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi

随机推荐