M. Black
M. Black

Reputation: 353

Why is ViewForAnnotation not called?

I know this question has been asked multiple times, however all of the answers seem slightly different than what is going on in my app.

My understanding is that the viewForAnnotation function is called once the mapView has its delegate set to the ViewController in which it is being displayed AND an annotation is being added to the map when the mapView scrolls so that it shows inside the mapView region.

Currently I have one main viewController (mainVC) that contains one MKMapView (mapView) This viewController controls four different maps to be displayed in mapView.

func moveViews(sender:Int) {
    // This function handles which button on the Segmented Control was clicked and the loads the appropriate map into the mapView (passed as a para

    removeAnnotationsAndOverlays() // ~~~
    if sender == 0 {
        // First Map was selected
        let map1VC = map1VC()
        map1VC.loadMap1View(mapView)
        map1VC.centerMapOnLocation()
    }
    else if sender == 1 {
        // Second Map was selected
        let map2VC = map2VC()
        map2VC.loadMap2View(mapView)
    }
    else if sender == 2 {
        // Third Map was selected
        let map3VC = map3VC()
        map3VC.loadMap3View(mapView)
    }
    else if sender == 3 {
        // Fourth Map was selected
        let map4VC = map4VC()
        map4VC.loadMap4View(mapView)
    }
    else {
        // Load First Map as default
        let map1VC = map1VC()
        map1VC.loadMap1View(mapView)
        map1VC.centerMapOnLocation()
    }
}

There are several different classes which controls the functionality of each of the different maps:

  1. Map 1 - Displays a combination of MKPolylines and Custom Annotations (inherits from MKAnnotation) that are read from a plist - This works great!
  2. Map 2 - Displays several MKPolylines read from a plist - This works great!
  3. Map 3 - Displays several MKPolylines read from a plist - This works great!
  4. Map 4 - Should display several Custom Annotations - this is NOT WORKING!

Here is what is happening with Map 4:

This works, however, I'm trying to customize the annotations that are being displayed but the ViewForAnnotation function is never called????

// This function is NEVER called
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
{
    // Define a reuse identifier. This is a string that will be used to ensure we reuse annotation views as much as possible.
    let identifier = "CemAnno"

    // Check whether the annotation we're creating a view for is one of our CemAnno objects.
    if annotation.isKindOfClass(CemAnno.self) {
        print("correct class")
        //let anno = annotation as! CustomAnnotation
        // Try to dequeue an annotation view from the map view's pool of unused views.
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)

        if annotationView == nil {
            print("no reusable view")
            // If it isn't able to find a reusable view, create a new one using MKPinAnnotationView and sets its canShowCallout property to be true. This triggers the popup with the name.
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView!.canShowCallout = true

            // Create a new UIButton using the built-in .Custom type. This is so we can add an image to the button.
            let btn = UIButton(type: .DetailDisclosure)
            //btn.setImage(anno.image, forState: .Normal)
            annotationView!.rightCalloutAccessoryView = btn
        } else {
            print("reusing a view")
            // If it can reuse a view, update that view to use a different annotation.
            annotationView!.annotation = annotation
        }

        return annotationView

    }

    // If the annotation isn't from a CustomClass, it must return nil so iOS uses a default view.
    return MKPinAnnotationView()
}

I've tried adding the location of a pin inside the current view region of the map but the ViewForAnnotation is never fired. I've tried adding the location of the pin outside of the current view region of the map but the ViewForAnnotation is never fired - I figured this should be the one that works, and as I 'scroll' the map and it shows up inside the current view region that should fire the function, but it doesn't (I should note that the pin is being displayed and shows up on the map).

This makes it so that I cannot customize the pin which I would like to do.

I'm using the same technique as Map 1 which works perfectly fine, but for some reason the ViewForAnnotation is never called inside Map 4.

Any suggestions would be greatly appreciated!!

Upvotes: 12

Views: 8452

Answers (3)

Stan
Stan

Reputation: 445

This is an incredibly dumb answer, but it's bit me twice today so here it is: check your latitude/longitude. If you have them swapped, you have an invalid point, or one in the middle of the ocean, so the view will never be requested as it is likely outside your visible rect.

Upvotes: 3

Massimo Polimeni
Massimo Polimeni

Reputation: 4906

Sorry but I can't see the declaration of your view controller mainVC: your controller implements the MKMapViewDelegate?

import MapKit

class mainVC: UIViewController, MKMapViewDelegate 
{
    ...
} 

EDIT 1: check also if in your view controller on your storyboard if the delegate is linked with your controller like this:

just right click on your mapView.

Upvotes: 9

wj2061
wj2061

Reputation: 6885

I encountered this problem from time to time.And I found that sometimes you need to call showAnnotations:animated: manually like this :

mapView.showAnnotations(mapView.annotations, animated: true)

Upvotes: 14

Related Questions