这个问题已经困扰了我几个星期了!
我有一个标签栏应用程序。在一个选项卡上,我输入点,在另一个选项卡上,点显示在地图上。引脚应根据点的类型而不同。
我面临的问题是每次从一个标签切换到另一个标签时,图钉图像会从应有的图像变为其他图像。例如,如果我在地图上有四个点,三个显示为圆形,另一个显示为三角形,则三角形将从一个点移动到另一个点。图像似乎随机变化。
所以,这是代码:
ViewController.m
-(void) viewWillAppear:(BOOL)animated
{
// Select the type of map
if (isMapSelected == NO) {
self.mapView.mapType = MKMapTypeSatellite;
}
else {
self.mapView.mapType = MKMapTypeStandard;
}
// Add region to the map (center and span)
[self addRegion];
// Removing old annotation
[self.mapView removeAnnotations:mapLocations];
// Initializing arrays for the annotations
mapLocations = [[NSMutableArray alloc]init];
[self addAnnotation];
}
-(void) addAnnotation
{
CLLocationCoordinate2D mapLocation;
IGAMapAnnotation *mapAnnotation;
// Calculate how many points are included
NSInteger numberOfPoints = [coordinatesTempArray count];
// Annotations will be added only of the flight plan includes at least one point
if (numberOfPoints > 0)
{
// Trying to add coordinates from the array of coordinates
for (NSInteger i=0; i < ([coordinatesTempArray count]); i++) {
mapAnnotation = [[IGAMapAnnotation alloc]init];
// Taking a point in the array and getting its coordinates
self.mapCoordinates = [coordinatesTempArray objectAtIndex:i];
// Getting a point in the array and getting its lattitude and longitude
self.mapLatitude = [[self.mapCoordinates objectAtIndex:0]doubleValue];
self.mapLongitude = [[self.mapCoordinates objectAtIndex:1]doubleValue];
// Assigning the point coordinates to the coordinates to be displayed on the map
mapLocation.latitude = self.mapLatitude;
mapLocation.longitude = self.mapLongitude;
// Adding coordinates and title to the map annotation
mapAnnotation.coordinate = mapLocation;
mapAnnotation.title = [navaidNamesTempArray objectAtIndex:i];
mapAnnotation.subtitle = nil;
mapAnnotation.navaidType = [navaidTypesTempArray objectAtIndex:i];
// Adding the annotation to the array that will be added to the map
[mapLocations addObject:mapAnnotation];
}
// Adding annotations to the map
[self.mapView addAnnotations:mapLocations];
}
}
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if([annotation isKindOfClass:[IGAMapAnnotation class]])
{
IGAMapAnnotation *myLocation = (IGAMapAnnotation *) annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"IGAMapAnnotation"];
if (annotationView == nil)
annotationView = myLocation.annotationView;
else
annotationView.annotation = annotation;
return annotationView;
}
else
return nil;
}
IGAMapAnnotation.m
@synthesize coordinate = _coordinate;
@synthesize title = _title;
@synthesize subtitle = _subtitle;
@synthesize type = _type;
// Tried to have this init method but was never able to make it work. Without it, the program crashes too!!!!
-(id)initWithTitle:(NSString *)newTitle Type:(NSString *)type Location:(CLLocationCoordinate2D) newCoordinate
{
self = [super init];
if (self) {
_title = newTitle;
_coordinate = newCoordinate;
_type = type;
}
return self;
}
-(MKAnnotationView *) annotationView {
MKAnnotationView *annotationView = [[MKAnnotationView alloc]initWithAnnotation:self reuseIdentifier:@"IGAMapAnnotation"];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
if ([self.type isEqual: @"A"] || [self.type isEqual: @"B"] || [self.type isEqual: @"C"])
{
annotationView.image = [UIImage imageNamed:@"circle.png"];
}
else if ([self.type isEqual: @"D"])
{
annotationView.image = [UIImage imageNamed:@"triangle.png"];
}
else if ([self.type isEqual: @"E"])
{
annotationView.image = [UIImage imageNamed:@"square.png"];
}
else
{
annotationView.image = [UIImage imageNamed:@"oval.png"];
}
return annotationView;
}
@end
就是这样。到目前为止,这种行为对我来说毫无意义。 谢谢你的帮助!
答案 0 :(得分:3)
这听起来像是一个注释视图重用问题。
当重新显示注释时,它们会重复使用带有先前注释图像的视图。视图中的image
属性在重新用于其他注释时应该不会更新。
在viewForAnnotation
委托方法中,此代码看起来不对:
MKAnnotationView *annotationView = [mapView dequeue...
if (annotationView == nil)
annotationView = myLocation.annotationView;
else
annotationView.annotation = annotation;
如果dequeue
返回一个视图(即先前创建的视图可能是为不同的类型的注释创建的),则其annotation
属性为已更新,但其image
属性未更新。
现有代码仅在创建新注释视图时设置image
属性(当dequeue
返回nil
时)。
现在,注释视图创建和image
- 设置代码位于注释模型类IGAMapAnnotation
中。最好创建一个自定义MKAnnotationView
类,在image
属性更新时自动更新annotation
属性。
但是,另一种方法是将所有逻辑放在viewForAnnotation
委托方法本身中(并从annotationView
类中删除IGAMapAnnotation
方法)。
更新后的viewForAnnotation
委托方法示例:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if (! [annotation isKindOfClass:[IGAMapAnnotation class]])
{
//return default view if annotation is NOT of type IGAMapAnnotation...
return nil;
}
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"IGAMapAnnotation"];
if (annotationView == nil)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"IGAMapAnnotation"];
//these properties don't change per annotation
//so they can be set only when creating a new view...
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else
{
annotationView.annotation = annotation;
}
//whether we are using a completely new view or a re-used view,
//set the view's image based on the current annotation...
IGAMapAnnotation *myLocation = (IGAMapAnnotation *) annotation;
if ([myLocation.type isEqual: @"A"] || [myLocation.type isEqual: @"B"] || [myLocation.type isEqual: @"C"])
{
annotationView.image = [UIImage imageNamed:@"circle.png"];
}
else if ([myLocation.type isEqual: @"D"])
{
annotationView.image = [UIImage imageNamed:@"triangle.png"];
}
else if ([myLocation.type isEqual: @"E"])
{
annotationView.image = [UIImage imageNamed:@"square.png"];
}
else
{
annotationView.image = [UIImage imageNamed:@"oval.png"];
}
return annotationView;
}