问题描述
我已经加载了带有大量自定义注释的MKMapView(大约800个).
I've got an MKMapView loaded with plenty of custom annotation (800 circa).
当我在地图上拖动并返回到注释时,其图像已被另一幅图像改变.对我来说,这似乎是一个缓存问题.
When I drag on the map and I return to an annotation, it's image has changed with another one. For me it's seems like a cache issue.
#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
SubClass(创建问题的标题)标题
#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
返回以前使用的视图时(当annotationView
不是nil
时) ,代码仅更新该视图的annotation
属性:
The dequeue is not being handled properly in viewForAnnotation
because when dequeueReusableAnnotationViewWithIdentifier
returns a previously-used view (when annotationView
is not nil
), the code is only updating that view's annotation
property:
if (annotationView == nil) {
annotationView = [location getAnnotationView];
} else {
annotationView.annotation = annotation;
}
但是注释视图的image
不会更新-在出队视图中,image
将设置为与为该视图最初创建的注释相关联的注释(当getAnnotationView
被调用).
But the annotation view's image
is not updated -- in a dequeued view, the image
will be set to the one associated with the annotation the view was originally created for (when getAnnotationView
was called).
因此,现在视图出现在新注释的坐标处,但是图像仍来自该视图用于的先前注释.
So now the view appears at the new annotation's coordinates but the image is still from the previous annotation the view was used for.
有多种解决方法,例如创建MKAnnotationView
的适当子类,以监视其annotation
属性的更改并自动更新与注释关联的所有其他属性.
There are various ways to fix this such as creating a proper subclass of MKAnnotationView
that monitors changes to its annotation
property and automatically updates all other properties associated with an annotation.
使用现有代码,一种简单的解决方法是将特定于注释的属性更改分离为一个单独的方法,该方法在创建视图和更新其annotation
属性时都可以调用.
With the existing code, a simple way to fix it is to separate out the annotation-specific property changes into a separate method that can be called both when the view is created and when its annotation
property is updated.
例如,在CompanyAnnotation
中,创建如下所示的方法:
For example, in CompanyAnnotation
, create a method like this:
-(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
属性将具有相同的问题.
Note that MapAnnotation
will have the same issue with the pinImageName
property.
这篇关于MKAnnotationView图像更改问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!