1

I cannot find an exact question to this.

I have some custom pins that look ok on a Standard map. I want to use other pins if the map changes to Satellite or Hybrid.

Is this possible?

I've tried this so far:

    annotationImageName = @"blackPin.png";

    if (segment == 1) {
        NSLog(@"segment 1");
        annotationImageName = @"whitePin.png";
    }
    else if (segment == 2) {
        NSLog(@"segment 2");
        annotationImageName = @"greyPin.png";
    }


}

......

MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotationPin"];

annotationView.image = [UIImage imageNamed:annotationImageName];
ICL1901
  • 7,632
  • 14
  • 90
  • 138

2 Answers2

1
 - (void) changeMapType: (id)sender
{
     annotationImageName = @"blackPin.png";

        if (mapView.mapType == MKMapTypeStandard)

         {

            mapView.mapType = MKMapTypeSatellite;
            NSLog(@"segment 1");
            annotationImageName = @"whitePin.png";
         } 
         else
          {
            mapView.mapType = MKMapTypeStandard;
            NSLog(@"segment 2");
           annotationImageName = @"greyPin.png";
          }

    } 

MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotationPin"];

annotationView.image = [UIImage imageNamed:annotationImageName];
ICL1901
  • 7,632
  • 14
  • 90
  • 138
Akash
  • 461
  • 2
  • 14
  • Thanks for that Akash, and welcome to SO. I don't think that annotationView is re-called when the map type segment is changed. – ICL1901 Jan 03 '16 at 19:07
1

You can make your own annotation view class that observes a custom notification that you will post when the mapType property of the map view changes:

@interface MyAnnotationView : MKAnnotationView
@property (nonatomic, strong) id<NSObject> observer;
@end

static NSString *kMapTypeChangeNotificationKey = @"com.domain.app.maptypechange";

@implementation MyAnnotationView

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self.observer];
}

- (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier mapType:(MKMapType)mapType {
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];

    if (self) {
        [self updateImageBasedUponMapType:mapType];

        typeof(self) __weak weakSelf = self;
        self.observer = [[NSNotificationCenter defaultCenter] addObserverForName:kMapTypeChangeNotificationKey object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
            MKMapType mapType = [note.userInfo[@"mapType"] unsignedIntegerValue];
            [weakSelf updateImageBasedUponMapType:mapType];
        }];
    }

    return self;
}

- (void)updateImageBasedUponMapType:(MKMapType)mapType {
    if (mapType == MKMapTypeStandard) {
        self.image = [UIImage imageNamed:@"whitePin.png"];
    } else if (mapType == MKMapTypeSatellite) {
        self.image = [UIImage imageNamed:@"greyPin.png"];
    } else {
        NSLog(@"Unexpected mapType %lu", (unsigned long)mapType);
    }
}

@end

Clearly, this means that when you instantiate it, you have to pass it a reference to the map type:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKUserLocation class]]) { return nil; }

    static NSString *reuseIdentifier = @"MyCustomAnnotation";

    MyAnnotationView *annotationView = (id)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
    if (annotationView) {
        annotationView.annotation = annotation;
    } else {
        annotationView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier mapType:mapView.mapType];
        annotationView.canShowCallout = true;
    }

    return annotationView;
}

Now, when you update the mapType of the map, also post this custom annotation:

- (IBAction)changedValueSegmentControl:(UISegmentedControl *)sender {
    if (sender.selectedSegmentIndex == 0) {
        self.mapView.mapType = MKMapTypeStandard;
    } else if (sender.selectedSegmentIndex == 1) {
        self.mapView.mapType = MKMapTypeSatellite;
    }

    [[NSNotificationCenter defaultCenter] postNotificationName:kMapTypeChangeNotificationKey object:self userInfo:@{@"mapType" : @(self.mapView.mapType)}];
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thank you Sir. What a brilliant answer. – ICL1901 Jan 04 '16 at 06:47
  • @DavidDelMonte - My original answer was using KVO, but that would present problems when the map view was deallocated. It's a little less elegant, but you can use custom notifications as shown in my revised answer. – Rob Jan 04 '16 at 07:19
  • Almost got it.. Is there possibly an error above? I get a compile error on `annotationView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier mapType:mapView.mapType]` – ICL1901 Jan 04 '16 at 15:04
  • @DavidDelMonte - In my original answer, I had `initWithAnnotation:reuseIdentifier:mapView:` and above I replaced that with `initWithAnnotation:reuseIdentifier:mapType:`. Did you catch that change? – Rob Jan 04 '16 at 16:28
  • oops. I had missed that – ICL1901 Jan 04 '16 at 20:31