Mapbox-gl-native: When instantiated from nib, MGLAnnotationView doesn't call the delegate methods when tapped

Created on 17 Jan 2017  路  8Comments  路  Source: mapbox/mapbox-gl-native

Platform:
iOs
Mapbox SDK version:
3.3.7

Steps to trigger behavior

  1. Create a MGLAnnotationViewSubclass
  2. Instantiate using nib
  3. tap the view

Expected behavior

The delegate methods should be called

func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
        debugPrint("asd")
        return true
    }
func mapView(_ mapView: MGLMapView, tapOnCalloutFor annotation: MGLAnnotation) {
        debugPrint("tapOncallout")
    }

Actual behavior

They don't get called. I have to instantiate the view using code, and init(withIdentifier). Since I cannot "set" the identifier after the view gets created instantiating the nib, could this be the problem?

annotations bug iOS needs information

Most helpful comment

ouch! it works 馃榿

All 8 comments

Can you include a snippet of your mapView(_:viewFor:) implementation and the subclass you are referring to?

sure:

func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {

        // This example is only concerned with point annotations.
        guard annotation is MGLPointAnnotation else {
            return nil
        }

        // Use the point annotation鈥檚 longitude value (as a string) as the reuse identifier for its view.
        let reuseIdentifier = "\(annotation.coordinate.longitude)"

        // For better performance, always try to reuse existing annotations.
        var annotationView:MGLAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? NowrAnnotationView

        // If there鈥檚 no reusable annotation view available, initialize a new one.
        if annotationView == nil {
            let nib = UINib(nibName: "NowrAnnotationView", bundle: Bundle.main)

            //annotationView?.reuseIdentifier = reuseIdentifier -> not allowed since it's read only
            annotationView = nib.instantiate(withOwner: self, options: nil).first as! NowrAnnotationView



        }else{
            debugPrint("reusing view!")
        }

        /*

         if annotationView == nil {
         annotationView = NowrAnnotationView(reuseIdentifier: reuseIdentifier)

         }else{
         debugPrint("reusing view!")
         }
         annotationView?.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
         */

        //annotationView!.bubbleView.isHidden = true
        return annotationView! as MGLAnnotationView
    }

and the subclass:

class NowrAnnotationView: MGLAnnotationView {
    @IBOutlet weak var imgNowr: UIImageView!
    @IBOutlet weak var bubbleView: UIView!
    @IBOutlet weak var lblEmoticons: UILabel!


    override func layoutSubviews() {
        super.layoutSubviews()


        // Force the annotation view to maintain a constant size when the map is tilted.
        scalesWithViewingDistance = false


        imgNowr.animationImages = [UIImage(named:"00.png")!, UIImage(named:"01.png")!, UIImage(named:"02.png")!, UIImage(named:"03.png")!, UIImage(named:"04.png")!]

        imgNowr.contentMode = .scaleAspectFit
        imgNowr.animationDuration = 1
        imgNowr.startAnimating()


         // Force the annotation view to maintain a constant size when the map is tilted.
         scalesWithViewingDistance = false


    }

I tried overriding the identifier, but the callout doesn't work.

var annotationView:NowrAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? NowrAnnotationView

        // If there鈥檚 no reusable annotation view available, initialize a new one.
        if annotationView == nil {
            let nib = UINib(nibName: "NowrAnnotationView", bundle: Bundle.main)

            annotationView = nib.instantiate(withOwner: self, options: nil).first as! NowrAnnotationView
            annotationView?.reuseIdentifier  = reuseIdentifier


        }else{
            debugPrint("reusing view!")
        }

Found the issue. The variable isEnabled is set to false when you instantiate with any other initializer than reuseIdentifier(reuseIdentifier:).

Try adding

annotationView?.isEnabled = true

ouch! it works 馃榿

@frederoni is this by design, or should this be considered a bug/feature?

thanks !

I'm going to reopen this since I think it'd be worthwhile to review how annotation views created with Interface Builder work with our view reuse system. Especially after https://github.com/mapbox/mapbox-gl-native/pull/6559 which manipulates the value of isEnabled.

Closing in favor of #7751

Was this page helpful?
0 / 5 - 0 ratings