1

I've got an array of places. Each of these places are displayed on a MapView and on a TableView on the same screen. I'd like to pop up the pin annotation of a place when I tap the corresponding row on the table view.

I've got the following code to populate annotations:

for (int i = 0; i < [self.myPlaces count]; i++)
    {
        MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
        SPlaces *ev = [self.myPlaces objectAtIndex:i];
        point.coordinate = CLLocationCoordinate2DMake([ev.location.latitude doubleValue], [ev.location.longitude doubleValue]);
        point.title = ev.title;
        point.subtitle = ev.type.name;
        [self.myMap addAnnotation:point];
    }

and this code to display an annotation when a row is selected on the TableView:

//row = tapped row on TableView
    [self.myMap selectAnnotation:[[self.myMap annotations] objectAtIndex:row] animated:YES];

The issue is that the annotations seems to have a random index in the myMap annotations array. I mean, i'd like to have this behavior:

users taps row 0 on Table view => annotation of pin 0 pops up on the map
users taps row 1 on Table view => annotation of pin 1 pops up on the map
users taps row 2 on Table view => annotation of pin 2 pops up on the map

But instead of this, I get:

users taps row 0 on Table view => annotation of pin 1 pops up on the map
users taps row 1 on Table view => annotation of pin 0 pops up on the map
users taps row 2 on Table view => annotation of pin 2 pops up on the map

...or any other random combination that change each time I restart the app. Note that if I enable user's location, one of my pin annotation can have it's title randomly changed for "Current location".

I'm pretty sure I'm note populating or accessing the annotation correctly. Do you have any clue ?

Thanks !

EDIT: This post seems to say that you have to scan your annotations array, looking for a matching title, then select the relevant annotation : Open Map Annotation from Selected Row in Table View Is this really the only way ? Since two pins could possibly share the same title, it seems a little bit hazardous...

Community
  • 1
  • 1
Quentin Hayot
  • 7,786
  • 6
  • 45
  • 62
  • You should be able to assign the row value to the `tag` of the Annotation and match it on that rather than title? – Flexicoder Feb 27 '14 at 17:15
  • MKPointAnnotation does not have any "tag" property. Maybe I'll have to use a custom AnnotationView... – Quentin Hayot Feb 27 '14 at 17:18
  • Ah sorry, I've used `MKPinAnnotationView` in the past which does have tag. I wonder after that if you could then use `[self.myMap viewWithTag:]` to get hold of the right one and select it that way? – Flexicoder Feb 27 '14 at 17:24

1 Answers1

1

The map view's annotations array is not guaranteed to return the annotations in the order that you added them.

This is partly due to the fact that if you have showsUserLocation set to YES, the annotations array returned by the map view includes the user location annotation even though you didn't explicitly call addAnnotation on it yourself. The map view adds that annotation internally so you have no control over the order.

The other reason is simply that the documentation doesn't say the array will be in any particular order.

See MKMapView annotations changing/losing order? for some more details.


As the answer you linked to suggests, one option is to search the annotations array until you find the one you're looking for that matches the criteria.

If your annotations are of type MKPointAnnotation, the only properties available are title, subtitle, and coordinate.

If these don't work for you (eg. if you can have annotations with the same title), you'll need to use a custom annotation class that has a property unique to each annotation.


However, note that the annotation class does not have to be a different class from your underlying data model class (eg. SPlaces).

It can simplify matters if your SPlaces class implements the MKAnnotation protocol itself. Then:

  • You won't need to loop through self.myPlaces and create separate annotation objects. Instead, you would have just the single line [self.myMap addAnnotations:self.myPlaces];.

  • You won't need to search through the map view's annotations array to find your SPlaces object. Instead, in didSelectRowAtIndexPath, you would be able to just do this:

    [self.myMap selectAnnotation:[self.myPlaces objectAtIndex:row] 
                        animated:YES];
    
Community
  • 1
  • 1
  • The MKAnnotation protocol seems really cool, I'll try that. Thanks ! – Quentin Hayot Feb 27 '14 at 17:53
  • @Anna I think I have an issue related to this question in some way. I really need someone to help look into [my question](http://stackoverflow.com/questions/28144466/how-to-select-map-pin-when-tapping-table-row-that-associates-with-it) and let me know what is wrong or what I'm missing. I'm very beginner, so really need some guidance here. Could you please help me out? Thanks. – SanitLee Jan 27 '15 at 14:48