MapView Pin注解的问题 – 当地图放大/平移/区域改变时,Pin会丢失颜色

我有一个mapview显示现金点的位置。 注释被删除,可以点击标注进入一个页面,有关该位置的更多细节。 有两类自由点,免费和付费,免费的自动提款机插针是绿色的,另一个是红色的。 当引脚下降时,它们是正确的颜色。 一切正常,直到我缩放到用户的位置或地图的其他领域,然后当我回到他们已经失去了他们的颜色格式的引脚,都是原来的红色。

我认为这是地图重新加载时,下载瓷砖,而不是正确地重新加载引脚,但我可能是错的。

任何帮助都感激不尽。

这里是我的代码:

#import "CashPointMapViewController.h" #import "PinDrop.h" #import "CashPointDetailViewController.h" @implementation CashPointMapViewController @synthesize app, theCashList, mapview, ann, count, myArray, pinColor; - (IBAction) getlocation { MKCoordinateRegion region; region.center = self.mapview.userLocation.coordinate; region.span.longitudeDelta = 0.01f; region.span.longitudeDelta = 0.01f; [mapview setRegion:region animated:YES]; } - (void)viewDidLoad { [super viewDidLoad]; mapview.showsUserLocation = YES; [mapview setMapType:MKMapTypeStandard]; [mapview setZoomEnabled:YES]; [mapview setScrollEnabled:YES]; MKCoordinateRegion region = { {0.0, 0.0 }, {0.0, 0.0 } }; region.center.latitude = 53.801279; region.center.longitude = -1.548567; region.span.longitudeDelta = 0.3f; region.span.longitudeDelta = 0.3f; [mapview setRegion:region animated:YES]; app = [[UIApplication sharedApplication]delegate]; UIImage *locate = [UIImage imageNamed:@"location arrow white.png"]; UIBarButtonItem *userlocatebutton = [[UIBarButtonItem alloc] initWithImage:locate style:UIBarButtonItemStylePlain target:self action:@selector(getlocation)]; self.navigationItem.rightBarButtonItem = userlocatebutton; [self performSelectorInBackground:@selector(annloop) withObject:self]; } -(void) annloop { int i; for (i=0; i<=count-1; i = i+1) { theCashList = [myArray objectAtIndex:i]; NSString *trimlat = [theCashList.lat stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSString *trimlon = [theCashList.lon stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; double latdouble = [trimlat doubleValue]; double londouble = [trimlon doubleValue]; CLLocationCoordinate2D coord = {(latdouble),(londouble)}; ann = [[PinDrop alloc] init]; ann.index = i; ann.title = [theCashList.name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSString *street = [theCashList.street stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSString *town = [theCashList.town stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSString *postcode = [theCashList.postcode stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSString *address = [[NSString alloc] initWithFormat:@"%@, %@, %@", street, town, postcode]; ann.subtitle = address; ann.coordinate = coord; NSString *trimprice = [theCashList.price stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if ([trimprice isEqualToString:@"Free"]) { ann.price = 1; } else { ann.price = 0; } [mapview performSelectorOnMainThread:@selector(addAnnotation:) withObject:ann waitUntilDone:YES]; } } -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { if ([annotation isKindOfClass:[MKUserLocation class]]) return nil; MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc]initWithAnnotation:ann reuseIdentifier:@"current"]; mypin.backgroundColor = [UIColor clearColor]; UIButton *goToDetail = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; mypin.rightCalloutAccessoryView = goToDetail; mypin.draggable = NO; mypin.animatesDrop = TRUE; mypin.canShowCallout = YES; if (ann.price == 1) { mypin.pinColor = MKPinAnnotationColorGreen; } else { mypin.pinColor = MKPinAnnotationColorRed; } return mypin; } - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { PinDrop *annView = view.annotation; CashPointDetailViewController *detailView = [[CashPointDetailViewController alloc]init]; theCashList = [myArray objectAtIndex:annView.index]; detailView.theCashList = theCashList; [self.navigationController pushViewController:detailView animated:YES]; } - (void)viewDidUnload { [super viewDidUnload]; } - (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end 

编辑:这是我的.h如果有帮助。

 #import <UIKit/UIKit.h> #import "AppDelegate.h" #import "CashPointList.h" #import <MapKit/MapKit.h> #import "PinDrop.h" @interface CashPointMapViewController : UIViewController { MKMapView *mapview; PinDrop *ann; } @property (nonatomic, retain) AppDelegate *app; @property (nonatomic, retain) CashPointList *theCashList; @property (nonatomic, retain) PinDrop *ann; @property (nonatomic, retain) IBOutlet MKMapView *mapview; @property (nonatomic, readwrite) int count; @property (nonatomic, retain) NSMutableArray *myArray; @property (nonatomic) MKPinAnnotationColor pinColor; -(IBAction) getlocation; @end 

这不是与地图重新加载瓦片相关的问题。

问题是viewForAnnotation委托中的代码使用了ann对象,并且错误的假设是,只要调用委托方法,类实例级ann对象就会同步。

viewForAnnotation委托不一定按照添加注释的顺序调用,如果地图需要重新显示注释时,可以多次调用相同的注释。

当委托方法被再次调用以前添加的注释时, annannotation不再指向同一个对象。 ann现在可能指向最后添加的注释,所以所有的注释都会改变为它的颜色。

在该委托方法中,您必须使用annotation参数,该参数是对当前调用 (可能与您的外部循环完全无关)的地图视图想要的视图的注释的引用。

所以这一行:

 MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc] initWithAnnotation:ann reuseIdentifier:@"current"]; 

应该:

 MKPinAnnotationView *mypin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"current"]; ^^^^^^^^^^ 

并在检查注释的属性时,使用annotation参数(并将其转换为您的自定义类以获取自定义属性):

 PinDrop *ann = (PinDrop *)annotation; //Note that this local "ann" is NOT the same as the class-level "ann". //May want to use a different name to avoid confusion. //The compiler may also warn you about this. if (ann.price == 1) ... 

单独的,不相关的,但强烈推荐的build议是通过使用dequeueReusableAnnotationViewWithIdentifier来实现注解视图重用。 当您有很多注释时,这会提高性能。