【问题标题】:Preventing Gestures From Going Through An Annotation View to the Map防止手势通过注释视图进入地图
【发布时间】:2018-10-14 00:17:32
【问题描述】:

我有一个 UIView,我要插入 MKAnnotationView。

它有一个以编程方式生成的手势识别器。

问题在于,有时,点击注释,也(或相反)进入地图。

我附上演示,归结为一个丑陋、简单的 ViewController(查看屏幕截图以了解它的外观)。

如果您使用它创建应用程序,然后在底部方块上反复点击/点击(点击/点击时颜色会改变),地图将放大。

它可能将某些点击解释为双击,但我不能确定(模拟器地图是 S L O W)。

防止注释下的手势识别器在注释中获取事件(甚至双击)的最佳方法是什么?

隐藏你的眼睛。这将是FUGLY:

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {
    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let washingtonMonument = CLLocationCoordinate2D(latitude: 38.8895, longitude: -77.0353)
        let annotation = GestureAnnotation()
        annotation.coordinate = washingtonMonument
        self.mapView.addAnnotation(annotation)
        let washingtonRegion = MKCoordinateRegion(center: washingtonMonument, span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
        self.mapView.setRegion(washingtonRegion, animated: false)
    }

    func mapView(_ inMapView: MKMapView, viewFor inAnnotation: MKAnnotation) -> MKAnnotationView? {
        if let annotation = inAnnotation as? GestureAnnotation {
            return annotation.viewObject
        }
        return nil
    }
}

class GestureTargetView: UIView {
    let colors = [UIColor.red, UIColor.yellow, UIColor.black, UIColor.green]
    var tapGestureRecognizer: UITapGestureRecognizer?
    var currentColorIndex = 0

    override func layoutSubviews() {
        if nil == self.tapGestureRecognizer {
            self.tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(type(of: self).handleTap))
            self.addGestureRecognizer(self.tapGestureRecognizer!)
        }
        self.backgroundColor = self.colors[0]
    }

    @objc func handleTap(sender: UITapGestureRecognizer) {
        if .ended == sender.state {
            self.currentColorIndex += 1
            if self.currentColorIndex == self.colors.count {
                self.currentColorIndex = 0
            }
            self.backgroundColor = self.colors[self.currentColorIndex]
        }
    }
}

class GestureAnnotationView: MKAnnotationView {
    var gestureView: GestureTargetView!

    override func prepareForDisplay() {
        self.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 128, height: 128))
        if nil == self.gestureView {
            self.gestureView = GestureTargetView(frame: self.frame)
            self.addSubview(self.gestureView)
        }
        super.prepareForDisplay()
    }
}

class GestureAnnotation: NSObject, MKAnnotation {
    var myView: GestureAnnotationView!
    var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0, longitude: 0)
    var viewObject: MKAnnotationView! {
        get {
            if nil == self.myView {
                self.myView = GestureAnnotationView(annotation: self, reuseIdentifier: "")
            }

            return self.myView
        }
    }
}

【问题讨论】:

  • 顺便说一句:为了清楚起见:上半部分有一个直接在 UIView 中实例化的 GestureTargetView 实例,而下半部分则在 GestureAnnotation 中。它们都会在点击时改变颜色。
  • 我认为你需要适当地设置gestureRecognizer的cancelsTouchesInView属性。 StackOverflow 中有一些很好的答案来描述这一点。我发现 Apple 自己的文档有点……不透明。
  • 谢谢!我想可能是这样。我将浏览该网站,看看是否可以挖掘出任何掘金。
  • 实际上,我看到了其他一些奇怪的行为,例如背景渲染不正确(在我正在处理的另一个更复杂的版本中)。似乎地图注释中的 UIViews 从系统中获得了某种“精简版事件”。就我而言,它肯定需要更多的研究。
  • 啊!我想我有。 Apple 文档很模糊,但看起来好像覆盖层中的视图本身没有收到事件。看来我需要使用 leftCalloutAccessoryView 来获取完整的 Monty。

标签: swift uiview mapkit uigesturerecognizer mkannotation


【解决方案1】:

只是想提一下我是如何“解决”这个问题的。

与许多此类事情一样,我必须想出一种完全不同的方法来做到这一点,而不是试图硬塞到黑客的地步。

我处理它的方式是创建一个透明的 UIView,我将它放置在 MapView 上的视图层次结构中。然后我将我的交互元素添加到此视图中,并在完成后刷新所有内容。

当你点击其他地方时,它有点奇怪,但没有任何东西接近地图平移或缩放时造成的损害。我想我想一想就能解决这个奇怪的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    • 1970-01-01
    相关资源
    最近更新 更多