MKAnnotationView图像更改问题

MKAnnotationView图像更改问题

本文介绍了MKAnnotationView图像更改问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经加载了带有大量自定义注释的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];
    }
}

请注意,MapAnnotationpinImageName属性将具有相同的问题.

Note that MapAnnotation will have the same issue with the pinImageName property.

这篇关于MKAnnotationView图像更改问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 16:06