mapkit 中的 iOS Pin 颜色问题
Posted
技术标签:
【中文标题】mapkit 中的 iOS Pin 颜色问题【英文标题】:iOS Pin color issue in mapkit 【发布时间】:2013-07-30 11:52:20 【问题描述】:我想要两种颜色的注释。为此,我使用了以下代码,
- (MKAnnotationView *)mapView:(MKMapView *)sender viewForAnnotation:(id <MKAnnotation>)annotation
static NSString *identifier = @"MyLocation";
if ([annotation isKindOfClass:[PlaceMark class]])
MKPinAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
@try
if (annotationView == nil)
annotationView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:identifier];
else
annotationView.annotation = annotation;
if([[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"])
annotationView.pinColor = MKPinAnnotationColorRed;
else
annotationView.pinColor = MKPinAnnotationColorGreen;
@catch (NSException *exception)
NSLog(@"nsCenterOrOffice exception = %@",exception);
return annotationView;
return nil;
但我仍然无法为所需的注释设置所需的颜色。有时特定的注释图钉颜色为红色,有时为绿色。我不明白为什么会这样。有谁能够帮助我 ?谢谢...
我修改了我的代码。这是我更新的代码
MapAnnotation.h
#import <MapKit/MapKit.h>
#import <Foundation/Foundation.h>
@interface MapAnnotation : MKPointAnnotation
NSString *title;
NSString *subtitle;
int dealLnk;
float latitude;
float longitude;
CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@property (nonatomic, assign) int dealLnk;
@property (nonatomic, assign) float latitude;
@property (nonatomic, assign) float longitude;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithTitle:(NSString *)ttl subTitle:(NSString *)subttl dealLink:(int)dealLnk latitude:(float)latitude longitude:(float)longitude andCoordinate:(CLLocationCoordinate2D)c2d;
@end
MapAnnotation.m
#import "MapAnnotation.h"
@implementation MapAnnotation
@synthesize title,subtitle,dealLnk,coordinate,latitude,longitude;
- (id)initWithTitle:(NSString *)ttl subTitle:(NSString *)subttl dealLink:(int)z latitude:(float)latitude1 longitude:(float)longitude1 andCoordinate:(CLLocationCoordinate2D)c2d
title = ttl;
subtitle = subttl;
dealLnk =z;
coordinate = c2d;
longitude = longitude1;
latitude = latitude1;
return self;
@end
这是我的实现文件
-(void)startAddingAnnotation
@try
CLLocationCoordinate2D annotationCoord;
z=0;
for (int i=0; i < [nslatitude count] ; i++,z++)
MapAnnotation *dealAnnotation = [[MapAnnotation alloc] init];
dealAnnotation.dealLnk = z;
annotationCoord.latitude = (CGFloat) [[nslatitude objectAtIndex:i] floatValue];
annotationCoord.longitude = (CGFloat)[[nslongitude objectAtIndex:i] floatValue];
dealAnnotation.coordinate = annotationCoord;
dealAnnotation.title = [nsCenterName objectAtIndex:i];
dealAnnotation.subtitle = [nsCenterAddress objectAtIndex:i];
NSLog(@"latitude = %f",dealAnnotation.latitude);
NSLog(@"longitude = %f",dealAnnotation.longitude);
NSLog(@"dealAnnotation.dealLnk = %d",dealAnnotation.dealLnk);
NSLog(@"dz = %d",z);
[mapView addAnnotation:dealAnnotation];
@catch (NSException *exception)
NSLog(@"Exception = %@",exception);
cord.longitude = -112.05186;
cord.latitude = 33.46577;
MKCoordinateRegion region;
region.center = cord;
MKCoordinateSpan span = .latitudeDelta = 1.0, .longitudeDelta = 1.0;
region.span = span;
[mapView setRegion:region];
#pragma mark - MapView_Delegate
- (MKAnnotationView *)mapView:(MKMapView *)sender viewForAnnotation:(id <MKAnnotation>)annotation
MapAnnotation *annotation1 = (MapAnnotation *)annotation;
z = annotation1.dealLnk;
NSLog(@"annotation1.longitude = %f",annotation1.latitude);
NSLog(@"annotation1.longitude = %f",annotation1.longitude);
if(z<[nslatitude count])
MKAnnotationView *pinView = nil;
static NSString *defaultPinID = @"pin1";
pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[MKAnnotationView alloc]
initWithAnnotation:annotation1 reuseIdentifier:defaultPinID];
pinView.canShowCallout = YES;
@try
if([[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"])
pinView.image = [UIImage imageNamed:@"flag1.png"];
else
pinView.image = [UIImage imageNamed:@"flag2.png"];
pinView.annotation = annotation1;
pinView.tag = [[nsCenterName objectAtIndex:z] intValue];
@catch (NSException *exception)
NSLog(@"nsCenterOrOffice exception = %@",exception);
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[pinView setRightCalloutAccessoryView:rightButton];
return pinView;
else
return nil;
现在的问题是,所有注释都指向不同的位置。我不明白为什么会这样?我的代码有什么问题吗?
【问题讨论】:
您检查您的条件 [[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"] 是否满足? 是的..该条件有效。该声明中没有问题。 那么你就可以用图片做pin了 更新代码的一个问题是 MapAnnotation 是 MKPointAnnotation 的子类,然后将坐标重新声明为只读。当代码稍后执行dealAnnotation.coordinate
时,此分配将执行到与新只读坐标的getter 将读取的不同的支持变量。结果,所有注释都可能变为 0,0。通常,自定义注释类应该只是 NSObject 的子类并实现 MKAnnotation protocol(例如MapAnnotation : NSObject<MKAnnotation>
)。而不是将坐标声明为readonly
,而是使用assign
。
【参考方案1】:
确定引脚颜色的条件是基于此委托方法外部的数据,并且不能保证它会与何时为特定注释调用此委托方法同步。
在这个if
条件下:
if([[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"])
z
变量显然是在这个委托方法之外声明和设置的一些实例变量(可能就在添加注释之前)。
同样,不保证viewForAnnotation
委托方法将在添加注释后立即被调用。也不能保证每个注释只调用一次委托方法。 因此z
值可能与调用委托方法的当前 annotation
不对应。
委托方法很可能在addAnnotation
被调用之后被调用,它的调用顺序与添加注解的顺序不同,并且每个注解都会被多次调用(例如. 如果用户平移或缩放地图并且注释重新出现)。
要解决此问题,请将“is center or office”属性添加到Placemark
类本身,并在创建注释和调用addAnnotation
时设置该属性之前。然后,在viewForAnnotation
方法中,您可以将annotation
参数转换为Placemark
并访问属性以实现条件。例如:
//where you create and add the annotation:
Placemark *pm = [[Placemark alloc...
pm.coordinate = ...
pm.title = ...
pm.centerOrOffice = [nsCenterOrOffice objectAtIndex:z];
[mapView addAnnotation:pm];
//in viewForAnnotation:
Placemark *myPlacemark = (Placemark *)annotation;
if ([myPlacemark.centerOrOffice isEqualToString:@"C"])
...
另一个不相关的问题是注释视图创建逻辑不太正确。
代码调用initWithAnnotation
两次,实际上第二个initWithAnnotation
永远不会被调用,因为第一次调用总是会成功。
您可能想要的是首先调用dequeueReusableAnnotationViewWithIdentifier:
,然后,如果返回nil
,则调用initWithAnnotation
。
在重构viewForAnnotation
中的代码时,请务必将设置pinColor
的代码在注解视图的dequeue/init 之外(例如,就在return annotationView;
之前)正确处理重用的视图。
【讨论】:
【参考方案2】:您的viewForAnnotation
依赖于一些外部变量nsCenterOrOffice
和z
。在您向我们展示如何设置这些变量之前,我们当然无法帮助您。
无论如何,这不是一个谨慎的做法。您的viewForAnnotation
通常应仅依赖于annotation
的属性,而不是外部变量。
【讨论】:
@user2260521 修改后的viewForAnnotation
看起来更有希望。这里有很多不同程度的问题(唯一明显的错误是initWithTitle
不调用[super init]
,但话说回来,你不使用这个方法,所以这不太可能是你的问题)。如果您的问题是注释添加正确,但只是添加了错误的图标,您应该在您的viewForAnnotation
中记录[nsCenterOrOffice objectAtIndex:z]
。如果您的问题是其他问题,请说明当前问题是什么。以上是关于mapkit 中的 iOS Pin 颜色问题的主要内容,如果未能解决你的问题,请参考以下文章
iOS MapKit更改mapview maptype会导致注释图像更改为pin?