LewTrocki
LewTrocki

Reputation: 41

UIButton in AnnotationView - How to keep icon and button

I need help with annotationView. What I'm going to do is to have already added icons, but when Im going to click the pin (icon) I would like to see the button in annotation view frame, as in this pictures: enter image description here

After I click it I would like to see this white frame and uibutton:

enter image description here

The way I found is to add var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) But I cant use this twice - you can see it in my code.

Here is my code:

    func znajdzSzczytyNaMapie(_ szczyty: [Szczyt]) {
      for szczyt in szczyty {
        let annotations = MKPointAnnotation()
        annotations.title = szczyt.name
        annotations.subtitle = szczyt.opis
        annotations.coordinate = CLLocationCoordinate2D(latitude:
          szczyt.lattitude, longitude: szczyt.longtitude)
        mapView.addAnnotation(annotations)
      }
    }

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard !(annotation is MKUserLocation) else { return nil }
        let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "MyMarker")
       // let identifier = "Gora"
       // var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) // The case is that obviously I cannot use let/var annotationView 2x times.
        let btn = UIButton(type: .detailDisclosure)
        annotationView.rightCalloutAccessoryView = btn
        switch annotation.title!! {
            case "Turbacz":
                annotationView.markerTintColor = UIColor(red: 0.86, green: 0.99, blue: 0.79, alpha: 1.00)
                annotationView.glyphImage = UIImage(named: "bald")
            case "example":
                annotationView.markerTintColor = UIColor(red: 0.80, green: 0.98, blue: 0.73, alpha: 1.00)
                annotationView.glyphImage = UIImage(named: "bear")
            default:
                annotationView.markerTintColor = UIColor.green
                annotationView.glyphImage = UIImage(named: "gora")
   } 
return annotationView
}

EDIT: Now I've got:

 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard !(annotation is MKUserLocation) else { return nil }
        //let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "MyMarker")
        let identifier = "identifier"
        guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView else { return nil }
        let btn = UIButton(type: .detailDisclosure)
        annotationView.rightCalloutAccessoryView = btn
        switch annotation.title!! {
            case "Turbacz":
                annotationView.markerTintColor = UIColor(red: 0.86, green: 0.99, blue: 0.79, alpha: 1.00)
                annotationView.glyphImage = UIImage(named: "bald")
            case "example":
                annotationView.markerTintColor = UIColor(red: 0.80, green: 0.98, blue: 0.73, alpha: 1.00)
                annotationView.glyphImage = UIImage(named: "bear")
            default:
                annotationView.markerTintColor = UIColor.green
                annotationView.glyphImage = UIImage(named: "gora")
   } 
return annotationView
}

but instead of my icons (See first image in this topic) and button, it shows custom annotation pin without button view:

enter image description here

Upvotes: 0

Views: 281

Answers (1)

Desdenova
Desdenova

Reputation: 5377

It looks like your code doesn't go beyond this line so it's returning the default annotation view. Also I misled you to the old dequeue method

Instead of this line;

guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView else { return nil }

Try this one, notice the extra for: annotation part;

guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as? MKMarkerAnnotationView else { return nil }

But for this to work, first you need to register the view before adding the annotations to the map view.

Add the below line of code, before you call func znajdzSzczytyNaMapie(_ szczyty: [Szczyt])

mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: "identifier")

After you got the hang of how this works, I suggest you to subclass marker annotation view and do your customizations inside that class to clean up code.

Upvotes: 1

Related Questions