MKAnnotationView 图像更改问题
MKAnnotationView image changing issue
我有一个加载了大量自定义注释的 MKMapView(大约 800)。
当我在地图上拖动并 return 到注释时,它的图像已与另一个不同。对我来说,这似乎是一个缓存问题。
拖动前固定
拖动后固定
超类header
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface MapAnnotation : NSObject <MKAnnotation>
@property (nonatomic, copy) NSString *title;
@property NSString * pinImageName;
@property (nonatomic) CLLocationCoordinate2D coordinate;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title pinImageName:(NSString *)pinImageName;
- (MKAnnotationView *)getAnnotationView;
@end
子类(产生问题的那个)header
#import "MapAnnotation.h"
#import "Company.h"
@interface CompanyAnnotation : MapAnnotation
@property Company *company;
@property UIImage *pinImage;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title pinImage:(UIImage *)pinImage;
- (MKAnnotationView *)getAnnotationView;
@end
viewForAnnotation 委托方法
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
if (annotation == mapView.userLocation){
return nil;
}
MapAnnotation *location = [MapAnnotation new];
MKAnnotationView *annotationView = [MKAnnotationView new];
if ([annotation isKindOfClass:[CompanyAnnotation class]]) {
location = (CompanyAnnotation *)annotation;
annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"companyAnnotation"];
}
if (annotationView == nil) {
annotationView = [location getAnnotationView];
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
getAnnotationView 方法
- (MKAnnotationView *)getAnnotationView {
MKAnnotationView * annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:@"companyAnnotation"];
[annotationView setEnabled:YES];
[annotationView setCanShowCallout:YES];
[annotationView setContentMode:UIViewContentModeScaleAspectFit];
[annotationView setImage:self.pinImage];
[annotationView setFrame:CGRectMake(0, 0, 28, 44)];
[annotationView setRightCalloutAccessoryView:[UIButton buttonWithType:UIButtonTypeDetailDisclosure]];
return annotationView;
}
在 viewForAnnotation
中未正确处理出队,因为当 dequeueReusableAnnotationViewWithIdentifier
returns 以前使用过视图(当 annotationView
不是 nil
时) ,代码仅更新该视图的 annotation
属性:
if (annotationView == nil) {
annotationView = [location getAnnotationView];
} else {
annotationView.annotation = annotation;
}
但是注释视图的 image
没有更新——在出队视图中,image
将被设置为与注释视图相关联的视图最初 为(调用 getAnnotationView
时)创建。
所以现在视图出现在新注释的坐标处,但图像仍然来自以前使用该视图的注释。
有多种方法可以解决此问题,例如创建 MKAnnotationView
的适当子类来监视对其 annotation
属性 的更改并自动更新与注释关联的所有其他属性。
使用现有代码,修复它的一个简单方法是将特定于注释的 属性 更改分离到一个单独的方法中,该方法可以在创建视图时及其 annotation
属性 已更新。
例如,在CompanyAnnotation
中,创建一个这样的方法:
-(void)configureView:(MKAnnotationView *)av
{
av.image = self.pinImage;
}
然后将getAnnotationView
改为:
- (MKAnnotationView *)getAnnotationView {
MKAnnotationView * annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:@"companyAnnotation"];
//set properties here that are not specific to an annotation...
[annotationView setEnabled:YES];
[annotationView setCanShowCallout:YES];
[annotationView setContentMode:UIViewContentModeScaleAspectFit];
//[annotationView setImage:self.pinImage];
[annotationView setFrame:CGRectMake(0, 0, 28, 44)];
[annotationView setRightCalloutAccessoryView:[UIButton buttonWithType:UIButtonTypeDetailDisclosure]];
//set properties that are specific to an annotation...
[self configureView:annotationView];
return annotationView;
}
终于在 viewForAnnotation
:
if (annotationView == nil) {
annotationView = [location getAnnotationView];
} else {
annotationView.annotation = annotation;
if ([annotation isKindOfClass:[CompanyAnnotation class]]) {
//update image, etc...
[annotation configureView:annotationView];
}
}
请注意 MapAnnotation
将与 pinImageName
属性 有相同的问题。
我有一个加载了大量自定义注释的 MKMapView(大约 800)。
当我在地图上拖动并 return 到注释时,它的图像已与另一个不同。对我来说,这似乎是一个缓存问题。
拖动前固定
拖动后固定
超类header
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface MapAnnotation : NSObject <MKAnnotation>
@property (nonatomic, copy) NSString *title;
@property NSString * pinImageName;
@property (nonatomic) CLLocationCoordinate2D coordinate;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title pinImageName:(NSString *)pinImageName;
- (MKAnnotationView *)getAnnotationView;
@end
子类(产生问题的那个)header
#import "MapAnnotation.h"
#import "Company.h"
@interface CompanyAnnotation : MapAnnotation
@property Company *company;
@property UIImage *pinImage;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title pinImage:(UIImage *)pinImage;
- (MKAnnotationView *)getAnnotationView;
@end
viewForAnnotation 委托方法
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
if (annotation == mapView.userLocation){
return nil;
}
MapAnnotation *location = [MapAnnotation new];
MKAnnotationView *annotationView = [MKAnnotationView new];
if ([annotation isKindOfClass:[CompanyAnnotation class]]) {
location = (CompanyAnnotation *)annotation;
annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"companyAnnotation"];
}
if (annotationView == nil) {
annotationView = [location getAnnotationView];
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
getAnnotationView 方法
- (MKAnnotationView *)getAnnotationView {
MKAnnotationView * annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:@"companyAnnotation"];
[annotationView setEnabled:YES];
[annotationView setCanShowCallout:YES];
[annotationView setContentMode:UIViewContentModeScaleAspectFit];
[annotationView setImage:self.pinImage];
[annotationView setFrame:CGRectMake(0, 0, 28, 44)];
[annotationView setRightCalloutAccessoryView:[UIButton buttonWithType:UIButtonTypeDetailDisclosure]];
return annotationView;
}
在 viewForAnnotation
中未正确处理出队,因为当 dequeueReusableAnnotationViewWithIdentifier
returns 以前使用过视图(当 annotationView
不是 nil
时) ,代码仅更新该视图的 annotation
属性:
if (annotationView == nil) {
annotationView = [location getAnnotationView];
} else {
annotationView.annotation = annotation;
}
但是注释视图的 image
没有更新——在出队视图中,image
将被设置为与注释视图相关联的视图最初 为(调用 getAnnotationView
时)创建。
所以现在视图出现在新注释的坐标处,但图像仍然来自以前使用该视图的注释。
有多种方法可以解决此问题,例如创建 MKAnnotationView
的适当子类来监视对其 annotation
属性 的更改并自动更新与注释关联的所有其他属性。
使用现有代码,修复它的一个简单方法是将特定于注释的 属性 更改分离到一个单独的方法中,该方法可以在创建视图时及其 annotation
属性 已更新。
例如,在CompanyAnnotation
中,创建一个这样的方法:
-(void)configureView:(MKAnnotationView *)av
{
av.image = self.pinImage;
}
然后将getAnnotationView
改为:
- (MKAnnotationView *)getAnnotationView {
MKAnnotationView * annotationView = [[MKAnnotationView alloc] initWithAnnotation:self reuseIdentifier:@"companyAnnotation"];
//set properties here that are not specific to an annotation...
[annotationView setEnabled:YES];
[annotationView setCanShowCallout:YES];
[annotationView setContentMode:UIViewContentModeScaleAspectFit];
//[annotationView setImage:self.pinImage];
[annotationView setFrame:CGRectMake(0, 0, 28, 44)];
[annotationView setRightCalloutAccessoryView:[UIButton buttonWithType:UIButtonTypeDetailDisclosure]];
//set properties that are specific to an annotation...
[self configureView:annotationView];
return annotationView;
}
终于在 viewForAnnotation
:
if (annotationView == nil) {
annotationView = [location getAnnotationView];
} else {
annotationView.annotation = annotation;
if ([annotation isKindOfClass:[CompanyAnnotation class]]) {
//update image, etc...
[annotation configureView:annotationView];
}
}
请注意 MapAnnotation
将与 pinImageName
属性 有相同的问题。