iOS MapKit - 是否可以根据地图类型更改地图图钉?
iOS MapKit - Is it possible to change a map pin based on map type?
我找不到确切的问题。
我有一些在标准地图上看起来不错的自定义图钉。如果地图更改为 Satellite 或 Hybrid,我想使用其他图钉。
这可能吗?
到目前为止我已经试过了:
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];
- (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];
您可以创建自己的注释视图 class,当地图视图的 mapType
属性 发生变化时,您将 post 观察自定义通知:
@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
时,还会 post 这个自定义注释:
- (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)}];
}
我找不到确切的问题。
我有一些在标准地图上看起来不错的自定义图钉。如果地图更改为 Satellite 或 Hybrid,我想使用其他图钉。
这可能吗?
到目前为止我已经试过了:
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];
- (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];
您可以创建自己的注释视图 class,当地图视图的 mapType
属性 发生变化时,您将 post 观察自定义通知:
@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
时,还会 post 这个自定义注释:
- (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)}];
}