0

In my project I fill my map with these informations

for  (int i = 0; i<arrayResults.count; i++){

        object = [arrayResults objectAtIndex:i];

        if ([[object iden]intValue] == 1) {

            type = @"type_one";

            CLLocationCoordinate2D annotationCoord = CLLocationCoordinate2DMake([[[object coord]objectForKey:@"latitude"] floatValue], [[[object coord]objectForKey:@"longitude"] floatValue]);

            MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
            annotationPoint.coordinate = annotationCoord;
            annotationPoint.title = [NSString stringWithFormat:@"%@",[object nome_obj]];
            annotationPoint.subtitle = [NSString stringWithFormat:@"%@",[object address]];
            [map addAnnotation:annotationPoint];
        }

        else if ([[object iden]intValue] == 2) {

          type = @"type_two";

            CLLocationCoordinate2D annotationCoord = CLLocationCoordinate2DMake([[[object coord]objectForKey:@"latitude"] floatValue], [[[object coord]objectForKey:@"longitude"] floatValue]);

            MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
            annotationPoint.coordinate = annotationCoord;
            annotationPoint.title = [NSString stringWithFormat:@"%@",[object nome_obj]];
            annotationPoint.subtitle = [NSString stringWithFormat:@"%@",[object address]];
            [map addAnnotation:annotationPoint];
        }

        else if ([[object iden]intValue] == 3) {

            type = @"type_three";

            CLLocationCoordinate2D annotationCoord = CLLocationCoordinate2DMake([[[object coord]objectForKey:@"latitude"] floatValue], [[[object coord]objectForKey:@"longitude"] floatValue]);

            MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
            annotationPoint.coordinate = annotationCoord;
            annotationPoint.title = [NSString stringWithFormat:@"%@",[object nome_obj]];
            annotationPoint.subtitle = [NSString stringWithFormat:@"%@",[object address]];
            [map addAnnotation:annotationPoint];
        }

        else if ([[object iden]intValue] == 4) {

            type = @"type_four";

            CLLocationCoordinate2D annotationCoord = CLLocationCoordinate2DMake([[[object coord]objectForKey:@"latitude"] floatValue], [[[object coord]objectForKey:@"longitude"] floatValue]);

            MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
            annotationPoint.coordinate = annotationCoord;
            annotationPoint.title = [NSString stringWithFormat:@"%@",[object nome_obj]];
            annotationPoint.subtitle = [NSString stringWithFormat:@"%@",[object address]];
            [map addAnnotation:annotationPoint];
        }

these are four type of object that I add on my map

when I enter inside this method

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {

    MKAnnotationView *view = nil;
    if (annotation != mapView.userLocation) {

            if ([[[arrayResults objectAtIndex:countPoint]iden]intValue] == 1){

                view = [mapView dequeueReusableAnnotationViewWithIdentifier:@"type_one"];
                if (!view) {

                    view = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"type_one"];
                    view.canShowCallout = YES;

                    UIButton* aButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
                    [aButton addTarget:self action:@selector(open:) forControlEvents:UIControlEventTouchUpInside];
                    [aButton setTag:countPoint+100];
                    view.rightCalloutAccessoryView = aButton;

                    view.image = [UIImage imageNamed:@"type_one.png"];
                }

            }

            else if ([[[arrayResults objectAtIndex:countPoint]iden]intValue] == 2){

                view = [mapView dequeueReusableAnnotationViewWithIdentifier:@"type_two"];
                if (!view) {

                    view = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"type_two"];

                    view.canShowCallout = YES;

                    UIButton* aButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
                    [aButton addTarget:self action:@selector(open:) forControlEvents:UIControlEventTouchUpInside];
                    [aButton setTag:countPoint+100];
                    view.rightCalloutAccessoryView = aButton;

                    view.image = [UIImage imageNamed:@"type_two.png"];
                }
            }
            else if ([[[arrayResults objectAtIndex:countPoint]iden]intValue] == 3){


                view = [mapView dequeueReusableAnnotationViewWithIdentifier:@"type_three"];
                if (!view) {

                    view = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"type_three"];

                    view.canShowCallout = YES;

                    UIButton* aButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
                    [aButton addTarget:self action:@selector(open:) forControlEvents:UIControlEventTouchUpInside];
                    [aButton setTag:countPoint+100];
                    view.rightCalloutAccessoryView = aButton;

                    view.image = [UIImage imageNamed:@"type_three.png"];
                }

            }
            else if ([[[arrayResults objectAtIndex:countPoint]iden]intValue] == 4){

                view = [mapView dequeueReusableAnnotationViewWithIdentifier:@"type_four"];
                if (!view) {

                    view = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"type_four"];

                    view.canShowCallout = YES;

                    UIButton* aButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
                    [aButton addTarget:self action:@selector(openScheda:) forControlEvents:UIControlEventTouchUpInside];
                    [aButton setTag:countPoint+100];
                    view.rightCalloutAccessoryView = aButton;

                  view.image = [UIImage imageNamed:@"type_four.png"];

                }
            }
countPoint++;
}

The problem is that type of marker don't correspond with array element... but I don't understand. That is if a marker has image "type_one", in the pop up it show "title" of type_four...it don't correspond

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
cyclingIsBetter
  • 17,447
  • 50
  • 156
  • 241
  • There is substantial duplicated code, that should be refactored into methods. There is a principle "DRY": Don't Repeat Yourself. The main reason is so if a change needs to be made it only has to be made in one place. It also makes the code easier to read and understand. – zaph Dec 31 '13 at 15:00
  • Central issue is you're assuming viewForAnnotation is called once after you call addAnnotation which is why you think `countPoint` should work. That assumption is just wrong. Please see: http://stackoverflow.com/questions/17946302/ios-pin-color-issue-in-mapkit, http://stackoverflow.com/questions/13745211/mkannotationview-fault-when-zoom-in-out-changed-the-pin-image, http://stackoverflow.com/questions/10898122/map-view-annotations-with-different-pin-colors. –  Dec 31 '13 at 15:07
  • Also, **_please_** do not use tags on the callout buttons to tell which annotation it is (aside from the fact that `countPoint` will give you wrong tags in the first place). There are much better and more reliable ways. See http://stackoverflow.com/questions/9462699/how-to-recognize-which-pin-was-tapped and http://stackoverflow.com/questions/9797047/how-to-keep-data-associated-with-mkannotation-from-being-lost-after-a-callout-po. –  Dec 31 '13 at 15:11

1 Answers1

3

Your annotation needs to "know" what type it is so you can create the right kind of view in viewForAnnotation. Do so by subclassing MKPointAnnotation, adding an NSInteger value to it to store the array index.

See MKPointAnnotation add extra property, but you'll add an NSInteger property called index.

When creating your annotations, set this property:

for  (int i = 0; i<arrayResults.count; i++)
{
    object = [arrayResults objectAtIndex:i];

    CLLocationCoordinate2D annotationCoord = CLLocationCoordinate2DMake([[[object coord]objectForKey:@"latitude"] floatValue], [[[object coord]objectForKey:@"longitude"] floatValue]);

    // MKMyPointAnnotation is your MKPointAnnotation subclass
    MKMyPointAnnotation *annotationPoint = [[MKMyPointAnnotation alloc] init];
    annotationPoint.coordinate = annotationCoord;
    annotationPoint.title = [NSString stringWithFormat:@"%@",[object nome_obj]];
    annotationPoint.subtitle = [NSString stringWithFormat:@"%@",[object address]];

    annotationPoint.index = i;                                // store the index

    [map addAnnotation:annotationPoint];
}

Then in your viewForAnnotation, cast the annotation to your subclass, then dereference the type:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
{
 MKMyPointAnnotation *myAnnotation = (MKMyPointAnnotation *)annotation;
 object = [arrayResults objectAtIndex:myAnnotation.index];      // <-- your index property

 switch ([[object iden] intValue])
 {
  case 1:                                 // type one
    .
    .
    .

 }

.
.
.
}
Community
  • 1
  • 1
CSmith
  • 13,318
  • 3
  • 39
  • 42
  • Although I agree that this solution is a step in the right direction, I would prefer that the annotation class hold a reference to the "parent" object from `arrayResults` itself instead of the _index_ in that array. By storing the index, the code in viewForAnnotation is unnecessarily forced to know about and refer to arrayResults and it also forces you to make sure arrayResults keeps the objects in that order. –  Dec 31 '13 at 15:21
  • 2
    It might also be better to simply make the objects in arrayResults _themselves_ conform to MKAnnotation in which case no new class is needed and one could simply call `addAnnotations` and pass `arrayResults` to add all the annotations in one shot (as well as solving the annotation reference issues). –  Dec 31 '13 at 15:24
  • true, in fact there wouldn't be any need for arrayResults if the annotation holds a reference to the object instead, or as suggested, the object IS the MKPointAnnotation subclass. Just trying to get closer to the right direction... – CSmith Dec 31 '13 at 15:26
  • after how can associate these annotations in didSelectAnnotationView ? – Gilberto Ibarra Mar 27 '15 at 22:52