如何在 Swift UIKit Map 组件中处理 SwiftUI 中的触摸手势?

Posted

技术标签:

【中文标题】如何在 Swift UIKit Map 组件中处理 SwiftUI 中的触摸手势?【英文标题】:How to handle touch gestures in SwiftUI in Swift UIKit Map component? 【发布时间】:2019-08-20 16:25:01 【问题描述】:

我尝试在 SwiftUI 应用程序中处理 Map UIKit 组件手势。 Xcode 显示此警告:“字符串文字不是有效的 Objective-C 选择器”

// Binding to UIKit component

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable 

    class Coordinator: NSObject, MKMapViewDelegate 
        @Binding var selectedPin: MapPin?

        init(selectedPin: Binding<MapPin?>) 
            self._selectedPin = selectedPin
        

        func mapView(_ mapView: MKMapView,
                     didSelect view: MKAnnotationView) 
            guard let pin = view.annotation as? MapPin else 
                return
            
            pin.action?()
            selectedPin = pin
        

        func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) 
            guard (view.annotation as? MapPin) != nil else 
                return
            
            selectedPin = nil
        
       

    @Binding var pins: [MapPin]
    @Binding var selectedPin: MapPin?

    func makeCoordinator() -> Coordinator 
      return Coordinator(selectedPin: $selectedPin)
    

    func makeUIView(context: Context) -> MKMapView 
        let view = MKMapView(frame: .zero)
        let gRecognizer = UITapGestureRecognizer(target: self, action: #selector(triggerTouchAction(gestureRecognizer:)))
          view.addGestureRecognizer(gRecognizer)
          view.delegate = context.coordinator
          return view
    

    func updateUIView(_ uiView: MKMapView, context: Context) 
        uiView.removeAnnotations(uiView.annotations)
        uiView.addAnnotations(pins)
        if let selectedPin = selectedPin 
            uiView.selectAnnotation(selectedPin, animated: false)
        
    

    @objc func triggerTouchAction(gestureReconizer: UITapGestureRecognizer) 
          //Add alert to show it works
        print("Hello, tap!")
    

我希望我的 Xcode 控制台中有消息,但没有产生触摸事件。

环境: Xcode 11 测试版 6 macOS Mojave 10.14.6

【问题讨论】:

【参考方案1】:

@objc 不能应用于结构内的函数。在 Coordinator 中移动函数,然后以这种方式更改 UIGestureRecognizer 声明:

let gRecognizer = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.triggerTouchAction(gestureReconizer:)))

【讨论】:

让gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(triggerTouchAction(gestureRecognizer:))) 错误:使用未解析的标识符'triggerTouchAction(gestureRecognizer:) @objc func triggerTouchAction(gestureReconizer: UITapGestureRecognizer) //添加警报以显示它有效 print("Hello, tap!") 错误:@objc 只能与类的成员一起使用,@ objc 协议和类的具体扩展 我不明白评论中的代码...编辑您的问题以包含它 MapPin 声明在哪里? @LorenzoSantini 谢谢你。这很棒。我按照相同的步骤实现了 UIPanGestureRecognizer,但是,我的选择器没有被调用。在查找原因时,我读到因为 MapKit 也实现了手势,所以有必要添加一个同时使用多个手势识别器的函数:真的 。但是,我仍然没有任何运气。请给点建议好吗?

以上是关于如何在 Swift UIKit Map 组件中处理 SwiftUI 中的触摸手势?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 UIKit 在 Swift 5 中立即强制更新我的 UI?

如何在 Swift UIKit 的 if 语句中显示多个警报?

如何使用 iOS Swift SKOverlay 和 UIKit 来交叉推广另一个应用程序?

如何在没有任何第三方库的情况下使用 UIKit 在 iOS 应用程序中使用 Swift 5 中的 GIF?

如何使用 UIKit 在 Swift 5 中创建具有内在高度的 UITableView?

在 Xcode 9 / Swift 4 中不再可以访问原生 UIKit 元素的子视图?