Custom MKAnnotationView touch zone is ridiculously narrow
Asked Answered
I

1

1

My custom MKAnnotationView subclass do not set it's image property. Instead, it handle some subviews to be displayed.

I implement public func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) in my delegate to detect annotation touch.

Because touch zone is by default calculated with the image property, my annotation view touch zone is about 1px large. This is ridiculous.

This is how I create it:

init(annotation: JZStreamAnnotation) {
    self.imageView = UIImageView.init(image: <an image>)
    self.imageView.contentMode = .center
    super.init(annotation: annotation, reuseIdentifier: JZStreamAnnotationView.identifier)
    self.canShowCallout = false
    self.imageView.center = CGPoint(x: self.frame.width/2, y: self.frame.height/2)
    self.addSubview(self.imageView)
}

I read this post, but I cannot figure out how the hitTest method works. Here an implementation that make nothing:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    if point.x > -100, point.x < 100, point.y > -100, point.y < 100 {
        //return self
        //return self.imageView
        return super.hitTest(point, with: event)
    }
    return .none
}

A breapoint located in the if clause fires, but returning whatever (super / self / imageView) does nothing.

Lastly, if I implement hitTest like this:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    return .none
}

and if I clic on my annotationView exact center, the public func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) delegate method if fired!

Any advice to enlarge the touch zone? 🤔

Isodiametric answered 1/9, 2017 at 10:13 Comment(0)
I
2

As far as I understood, func point(inside:with:) and hitTest(point:with:) do not help to enlarge the zone which call the delegate public func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)

Finally, I ended up by enlarging the MKAnnotationView frame to enclose my annotation subviews and moving the anchor point to be exactly where I wanted my annotation center

self.frame = CGRect(x: 0, y: 0, width: 
self.myLabel.frame.width, height: self.myLabel.frame.height)
self.centerOffset = CGPoint(x: self.frame.width/2, y: self.myImageView.frame.height/2)

Then I deleted point(inside:with:) and hitTest(point:with:) overrides that did nothing.

That's the only way I succeeded to make my annotation view fully reactive.

Isodiametric answered 19/9, 2017 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.