显示自定义多个引脚会显示位置错误的引脚 [英] Displaying custom multiple pins shows wrong pins for locations
问题描述
这个问题已经困扰了我几个星期了!
This problem has been bugging me for a couple of weeks already!
我有一个标签栏应用程序.在一个选项卡上,我输入点,在另一个选项卡上,点显示在地图上.引脚应根据点的类型而有所不同.
I have a tab bar application. On one tab I am entering points, and on another tab, the points are displayed on a map. Pins should be different dependent on the types of points.
我面临的问题是,每当我从一个选项卡切换到另一个选项卡时,固定图像都会从应有的图像变为其他图像.例如,如果我在地图上有四个点,三个点显示为一个圆,一个显示为三角形,则该三角形将从一个点移动到另一个点.图像似乎随机变化.
The problem that I face is that every time I switch from one tab to another, the pin images change from what they should be to other images. For example, if I have four points on the map, three displayed as a circle and one as a triangle, the triangle will be moving around from one point to another. Images seem to change quite randomly.
所以,这是代码:
ViewController.m
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
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
就是这样.到目前为止,这种行为对我来说毫无意义. 感谢您的帮助!
This is it. So far, the behaviour makes no sense to me. Thanks for your help!
推荐答案
这听起来像是注释视图的重用问题.
It sounds like an annotation view re-use issue.
重新显示注释时,它们将重新使用带有先前注释图像的视图.视图中的image
属性未得到更新,因为它已被重新用于另一个注释.
When the annotations are re-displayed, they are re-using views with the images of previous annotations. The image
property in the view is not being updated as it should be when it is re-used for another annotation.
在viewForAnnotation
委托方法中,此代码看起来不正确:
In the viewForAnnotation
delegate method, this code looks wrong:
MKAnnotationView *annotationView = [mapView dequeue...
if (annotationView == nil)
annotationView = myLocation.annotationView;
else
annotationView.annotation = annotation;
如果dequeue
返回一个视图(即先前创建的视图,该视图可能是为不同类型的注释创建的),则其annotation
属性会更新,但其image
属性未更新.
If the dequeue
returns a view (ie. a previously-created view that may have been created for an annotation of a different type), its annotation
property is updated but its image
property is not updated.
现有代码仅在创建新的注释视图时(dequeue
返回nil
时)设置image
属性.
The existing code only sets the image
property when creating a new annotation view (when dequeue
returns nil
).
现在,注释 view 的创建和image
设置代码位于注释 model 类IGAMapAnnotation
中.最好创建一个自定义的MKAnnotationView
类,该类在annotation
属性更新时自动更新image
属性.
Right now, the annotation view creation and image
-setting code is in the annotation model class IGAMapAnnotation
. It would be better to create a custom MKAnnotationView
class that automatically updates the image
property whenever its annotation
property is updated.
但是,另一种选择是将所有逻辑放在viewForAnnotation
委托方法本身中(并从IGAMapAnnotation
类中删除annotationView
方法).
However, another alternative is to put all the logic in the viewForAnnotation
delegate method itself (and remove the annotationView
method from the IGAMapAnnotation
class).
更新的viewForAnnotation
委托方法的示例:
Example of the updated viewForAnnotation
delegate method:
-(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;
}
这篇关于显示自定义多个引脚会显示位置错误的引脚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!