iOS SwiftUI技术求助:检测Mapbox地图视图上UITapGesture位置的代码问题排查
解决Mapbox UIViewRepresentable手势识别的两个问题
嘿,我来帮你搞定这两个Mapbox + SwiftUI的问题,咱们一个个来解决:
问题1:tappedMap函数内代码编译失败
你的两行代码编译报错,核心原因是参数类型不匹配:
- 第一行
sender.location(in: control):control是你的Map结构体实例,而location(in:)要求传入UIView类型的对象,你应该传入实际的地图视图。 - 第二行
sender.convert(...):convert(_:toCoordinateFrom:)是MGLMapView的专属方法,手势识别器UITapGestureRecognizer并没有这个方法,而且同样control不是合法的参数。
解决方案
修改Coordinator里的tappedMap方法,先获取到地图视图实例,再调用正确的方法:
@objc func tappedMap(sender: UITapGestureRecognizer) { // 先确保手势识别器的关联视图是MGLMapView guard let mapView = sender.view as? MGLMapView else { return } // 获取点击在地图视图内的坐标点 let tapPoint = sender.location(in: mapView) // 把视图坐标转换成地图经纬度 let tappedCoordinate = mapView.convert(tapPoint, toCoordinateFrom: mapView) // 这里可以添加你的业务逻辑,比如打印经纬度 print("用户点击了地图:\(tappedCoordinate.latitude), \(tappedCoordinate.longitude)") }
问题2:带参数时点击地图崩溃
崩溃的原因是Selector字符串和方法签名不匹配:
你创建手势识别器时用了Selector("tappedMap"),但你的方法是带参数的(sender: UITapGestureRecognizer),此时Selector需要加上冒号来匹配带参数的方法,也就是Selector("tappedMap:")。不过更推荐用类型安全的#selector语法,它能在编译阶段就检查方法是否存在,避免拼写错误导致的崩溃。
解决方案
修改makeUIView里的手势识别器创建代码:
let gestureRecognizer = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.tappedMap(sender:)))
额外注意:重复定义的makeCoordinator方法
你的代码里重复写了两次makeCoordinator(),这会导致编译错误,记得删掉其中一个,保留正确的版本,比如保留:
func makeCoordinator() -> Map.Coordinator { Coordinator(self) }
完整修正后的代码
struct Map: UIViewRepresentable { private let mapView: MGLMapView = MGLMapView(frame: .zero, styleURL: MGLStyle.streetsStyleURL) func makeUIView(context: UIViewRepresentableContext<Map>) -> MGLMapView { mapView.delegate = context.coordinator // 使用#selector语法创建手势识别器 let gestureRecognizer = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.tappedMap(sender:))) mapView.addGestureRecognizer(gestureRecognizer) return mapView } func updateUIView(_ uiView: MGLMapView, context: UIViewRepresentableContext<Map>) { print("Just updated the mapView") } // 只保留一个makeCoordinator方法 func makeCoordinator() -> Map.Coordinator { Coordinator(self) } final class Coordinator: NSObject, MGLMapViewDelegate { var control: Map init(_ control: Map) { self.control = control } // 修正后的点击处理方法 @objc func tappedMap(sender: UITapGestureRecognizer) { guard let mapView = sender.view as? MGLMapView else { return } let tapPoint = sender.location(in: mapView) let tappedCoordinate = mapView.convert(tapPoint, toCoordinateFrom: mapView) print("Tapped coordinate: \(tappedCoordinate)") } // 这里保留你的其他MGLMapViewDelegate方法 } }
内容的提问来源于stack exchange,提问作者nickcoding
相关产品推荐
相关产品推荐

