redman
redman

Reputation: 335

mapView:didAddAnnotationViews doesn't always pick up the annotations

I have placed a number of annotations on a map, and when the user touches the location button, the view zooms in on the user location, which contains a number of annotations.

mapView:didAddAnnotationViews is called and should add all the annotations inside the current view into an NSArray.

Sometimes it adds all the annotations without any problems, but other times, it only adds the one annotation which is the user location (blue dot).

I suspect it may have to do with being called before the map has finished rendering, but i'm not sure.

Not sure if it's possible to link the function mapViewDidFinishRenderingMap to didAddAnnotationViews so that it will only load once the view has been completed loading (including all the annotations).

Would appreciate any advice regarding this, as I am relatively new to Swift.

Here's some of my code. I've got a timer that runs every second and prints out the size of the array in the console.

var timer = NSTimer()
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update", userInfo: nil, repeats: true)

func mapView (mapView: MKMapView!, didAddAnnotationViews views: [AnyObject]!) {

    pinannotationarray = views

}   

func update() {

    if (pinannotationarray != nil && locationManager.location != nil)
     {
       println("pinannotationarray size \(pinannotationarray.count)")
     }
}

** Revised Code **

var annSet: AnyObject!

func mapView(mapView: MKMapView!, regionDidChangeAnimated animated: Bool) {

annSet = mapView.annotationsInMapRect(mapView.visibleMapRect)
println("regionDidChangeAnimate: annSet count = \(annSet.count)")

for (var i = 0; i < annSet.count; i++)
    {
    pinannotation = annSet.allObjects[i].annotation as? MyAnnotation

    //fatal error: unexpectedly found nil while unwrapping an Optional value       
    println(pinannotation.title)
    }
}

Upvotes: 1

Views: 962

Answers (1)

user467105
user467105

Reputation:

The annotationsInMapRect method returns an NSSet containing the annotation model objects (eg. MKPointAnnotation) -- not the views (eg. MKAnnotationView).

That also means annSet.allObjects will be an NSArray containing the annotation model objects.

That means annSet.allObjects[i].annotation is invalid and will fail (annotation views have an annotation property and not the annotations themselves) which leaves pinannotation as nil resulting in the crash.

Change the assignment to:

pinannotation = annSet.allObjects[i] as? MyAnnotation
println(pinannotation.title)

or to be a little safer:

if let pa = annSet.allObjects[i] as? MyAnnotation {
    println(pa.title)
}


By the way, you don't even need to generate an NSArray from the NSSet. You can iterate the NSSet directly:

for ann in annSet as NSSet {
    if let ma = ann as? MyAnnotation {
        println("ma.title = \(ma.title)")
    }
}

Upvotes: 1

Related Questions