【问题标题】:iOS MapKit - Is it possible to change a map pin based on map type?iOS MapKit - 是否可以根据地图类型更改地图图钉?
【发布时间】:2016-01-03 17:49:11
【问题描述】:

我找不到确切的问题。

我有一些在标准地图上看起来不错的自定义图钉。如果地图更改为卫星或混合,我想使用其他图钉。

这可能吗?

到目前为止我已经尝试过了:

    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];

【问题讨论】:

    标签: ios mapkit mapkitannotation


    【解决方案1】:

    您可以创建自己的注释视图类,该类观察自定义通知,当地图视图的mapType 属性更改时您将发布该通知:

    @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
    

    显然,这意味着当您实例化它时,您必须将其传递给映射类型的引用:

    - (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;
    }
    

    现在,当您更新地图的mapType 时,也要发布此自定义注释:

    - (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)}];
    }
    

    【讨论】:

    • 谢谢先生。多么精彩的答案。
    • @DavidDelMonte - 我最初的回答是使用 KVO,但是当地图视图被释放时会出现问题。它不太优雅,但您可以使用我修改后的答案中显示的自定义通知。
    • 差不多明白了..上面可能有错误吗?我在annotationView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier mapType:mapView.mapType] 上收到编译错误
    • @DavidDelMonte - 在我原来的答案中,我有initWithAnnotation:reuseIdentifier:mapView: 和上面我用initWithAnnotation:reuseIdentifier:mapType: 替换它。你发现变化了吗?
    • 哎呀。我错过了
    【解决方案2】:
     - (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];
    

    【讨论】:

    • 感谢 Akash,欢迎来到 SO。我认为更改地图类型段时不会重新调用annotationView。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 2012-03-19
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多