自定义地图视图类Swift

自定义地图视图类Swift,swift,mkmapview,uitapgesturerecognizer,Swift,Mkmapview,Uitapgesturerecognizer,我遇到了一些重大问题,需要一些帮助。我用的是公司的代码What3Words。他们创建了一个自定义类: open class MapView: MKMapView, MKMapViewDelegate, UIGestureRecognizerDelegate, CLLocationManagerDelegate { //all their code is here } 我的目标是使用轻触手势,以便从地图中获取纵横比。当使用MapViewKit插件时,我可以非常轻松地完成这项工作,并且我使对象符合

我遇到了一些重大问题,需要一些帮助。我用的是公司的代码What3Words。他们创建了一个自定义类:

open class MapView: MKMapView, MKMapViewDelegate, UIGestureRecognizerDelegate, CLLocationManagerDelegate {
//all their code is here
}
我的目标是使用轻触手势,以便从地图中获取纵横比。当使用MapViewKit插件时,我可以非常轻松地完成这项工作,并且我使对象符合MKMapView


    @IBOutlet weak var map: MKMapView!
    let locationManager = CLLocationManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    @IBAction func tapped(_ sender: UITapGestureRecognizer) {
        print("hey")
    let tap = sender
        let coord = tap.location(in: map)
        print(coord)
        print(tap.location(in: self))
        print(tap.location(in: map))
        map.convert(coord, to: map)
        print(map.convert(coord, to: map))
        
    }

}
但是,如果我符合MKMapView!我无法访问开放类中的任何专业代码。 如果我让它符合公开课,我不知道如何使用我的轻拍手势

我应该在下面的任何VC中调用此代码,我希望地图显示在其中:

    super.viewDidLoad()

    let map = MapViewController(frame: view.frame)
    map.set(api: api)
    map.set(center: "school.truck.lunch", latitudeSpan: 0.05, longitudeSpan: 0.05)
    map.showsUserLocation = true

    
    map.onError = { error in
      self.showError(error: error)
    }
    
    self.view = map
}

  // MARK: Show an Error
  
  /// display an error using a UIAlertController, error messages conform to CustomStringConvertible
  func showError(error: Error) {
    DispatchQueue.main.async {
      let alert = UIAlertController(title: "Error", message: String(describing: error), preferredStyle: .alert)
      alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler: nil))
      self.present(alert, animated: true)
    }
  }

你知道我如何在仍然使用这个特殊类的情况下让轻拍动作起作用吗?我觉得我什么都试过了。啊!!请协助。

最简单的方法是将以下内容添加到您的ViewController中:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let location = touches.first?.location(in: map) {
      map.screenCoordsToWords(point: location) { square in
        print(square.words ?? "")
      }
    }
  }
但这样做可能会导致MKMapView的touch事件处理程序和视图控制器之间的混淆。这取决于你想完成什么,可能是好的,也可能不是好的

如果出现问题,您可以在MapView中附加一个手势识别器,但有一个技巧可以防止覆盖MKMapView的内置双击识别器:

  func addGesture() {
    /// when the user taps the map this is called and it gets the square info
    let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
    tap.numberOfTapsRequired = 1
    tap.numberOfTouchesRequired = 1
    
    // A kind of tricky thing to make sure double tap doesn't trigger single tap in MKMapView
    let doubleTap = UITapGestureRecognizer(target: self, action:nil)
    doubleTap.numberOfTapsRequired = 2
    addGestureRecognizer(doubleTap)
    tap.require(toFail: doubleTap)
    
    tap.delegate = self
    
    addGestureRecognizer(tap)
  }

  
  @objc func tapped(_ gestureRecognizer : UITapGestureRecognizer) {
    let location = gestureRecognizer.location(in: self)
    let coordinates = convert(location, toCoordinateFrom: self)
    api?.convertTo3wa(coordinates: coordinates, language: "en") { square, error in
      if let s = square {
        print(s.words ?? "")
      }
    }
  }
然后在ViewController的viewDidLoad中进行设置:

map.addGesture()

最简单的方法是将以下内容添加到ViewController:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let location = touches.first?.location(in: map) {
      map.screenCoordsToWords(point: location) { square in
        print(square.words ?? "")
      }
    }
  }
但这样做可能会导致MKMapView的touch事件处理程序和视图控制器之间的混淆。这取决于你想完成什么,可能是好的,也可能不是好的

如果出现问题,您可以在MapView中附加一个手势识别器,但有一个技巧可以防止覆盖MKMapView的内置双击识别器:

  func addGesture() {
    /// when the user taps the map this is called and it gets the square info
    let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
    tap.numberOfTapsRequired = 1
    tap.numberOfTouchesRequired = 1
    
    // A kind of tricky thing to make sure double tap doesn't trigger single tap in MKMapView
    let doubleTap = UITapGestureRecognizer(target: self, action:nil)
    doubleTap.numberOfTapsRequired = 2
    addGestureRecognizer(doubleTap)
    tap.require(toFail: doubleTap)
    
    tap.delegate = self
    
    addGestureRecognizer(tap)
  }

  
  @objc func tapped(_ gestureRecognizer : UITapGestureRecognizer) {
    let location = gestureRecognizer.location(in: self)
    let coordinates = convert(location, toCoordinateFrom: self)
    api?.convertTo3wa(coordinates: coordinates, language: "en") { square, error in
      if let s = square {
        print(s.words ?? "")
      }
    }
  }
然后在ViewController的viewDidLoad中进行设置:

map.addGesture()

这起作用令人惊讶。谢谢如果我想突出显示我点击的不同颜色的磁贴,我会在点击的@objc func中放置.addOverlay和.removeOverlay吗?假设“磁贴”是指三个字地址周围的正方形,我想你可能会为要突出显示的正方形创建一个新的覆盖,或者修改当前栅格中的栅格绘制算法以高亮显示特定的正方形。但是是的,我不明白为什么你不能在
函数中调用一些东西来设置它。顺便说一句,闭包的
square
参数包含所选三字地址的正方形边界的坐标(
southWestBounds
+
northwestbounds
)。谢谢如果我想突出显示我点击的不同颜色的磁贴,我会在点击的@objc func中放置.addOverlay和.removeOverlay吗?假设“磁贴”是指三个字地址周围的正方形,我想你可能会为要突出显示的正方形创建一个新的覆盖,或者修改当前栅格中的栅格绘制算法以高亮显示特定的正方形。但是是的,我不明白为什么你不能在
函数中调用一些东西来设置它。顺便提一下,闭包的
square
参数包含所选三字地址的正方形边界的坐标(
southWestBounds
+
northwestbounds
)。