根据所选的MKAnnotationView动态更改leftCalloutAccessoryView

时间:2014-08-11 16:51:08

标签: ios mkannotationview

我有一组图像,与我地图上的每个Annotation相关联。我可以静态地将图像添加到leftCalloutAccessoryView,但我不确定如何使其动态化。我希望清楚我要问的是什么。每个注释都有自己想要显示的单独图像,但我不确定如何通过以下方法引用图像;

- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
{
    if([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

    NSString *annotationIdentifier = @"PinViewAnnotation";

    MyAnnotationView *pinView = (MyAnnotationView *) [mv dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];


    if (!pinView)
    {
        pinView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];

       pinView.canShowCallout = YES;

       UIImageView *houseIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Icon"]];//static image
        [houseIconView setFrame:CGRectMake(0, 0, 30, 30)];
        pinView.leftCalloutAccessoryView = houseIconView;

    }
    else
    {
        pinView.annotation = annotation;
    }

    return pinView;

}

我的数组“self.sandwiches”包含Sandwich个具有名称(NSString)和imageName('NSString')的对象。

我正在寻找一个解决方案,我可以获取所选引脚的索引,类似于UITableView,您可以在其中获取索引,并使用indexPath.row从数组中访问它。< / p>

我的注释课程; 。H     #进口     #进口     #import

@interface SandwichAnnotation : NSObject<MKAnnotation>
@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
@property (nonatomic,copy) NSString * title;
@property (nonatomic,copy) NSString * subtitle;

@end

的.m

#import "SandwichAnnotation.h"

@implementation SandwichAnnotation
@synthesize coordinate,title,subtitle;

@end

1 个答案:

答案 0 :(得分:2)

viewForAnnotation中,而不是&#34;获取引脚的索引&#34; (这会起作用但效率低于UITableView),我建议添加注释类本身所需的数据。

这样,数据更加自包含,委托方法或其他地方的代码不需要担心,知道或与注释对象的位置或类型结构保持同步< em>存储 in。只要您有对注释对象的引用,您将立即获得该注释所需的所有数据(或者至少它将包含对自身内相关数据的引用)。

viewForAnnotation委托方法提供了对其需要查看的注释对象的引用(annotation参数)。它的输入通常为id<MKAnnotation>,但它实际上是您创建的确切类型的实例(由您SandwichAnnotation或地图视图为MKUserLocation


一种选择是让父Sandwich类本身实现MKAnnotation并消除SandwichAnnotation类。这样,根本不需要搜索或引用,因为annotation参数实际上 Sandwich


但是,您可能希望为注释对象保留一个单独的类(这很好)。在这种情况下,您可以在注记类中添加对父对象的引用。例如:

@interface SandwichAnnotation : NSObject<MKAnnotation>
@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
@property (nonatomic,copy) NSString * title;
@property (nonatomic,copy) NSString * subtitle;
@property (nonatomic,retain) Sandwich * whichSandwich;  // <-- add reference
@end

创建SandwichAnnotation时,请设置注释所针对的Sandwich的引用:

for (Sandwich *currentSandwich in self.sandwiches) {
    SandwichAnnotation *sa = [[SandwichAnnotation alloc] init...];
    sa.coordinate = ...
    sa.title = ...
    sa.whichSandwich = currentSandwich; // <-- set reference

    [mapView addAnnotation:sa];
}

最后,在viewForAnnotation中,如果annotation的类型为SandwichAnnotation,请设置leftCalloutAccessoryView

- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
{
    if (! [annotation isKindOfClass:[SandwichAnnotation class]]) {
        //If annotation is not a SandwichAnnotation, return default view...
        //This includes MKUserLocation.
        return nil;
    }

    //At this point, we know annotation is of type SandwichAnnotation.
    //Cast it to that type so we can get at the custom properties.
    SandwichAnnotation *sa = (SandwichAnnotation *)annotation;

    NSString *annotationIdentifier = @"PinViewAnnotation";

    MyAnnotationView *pinView = (MyAnnotationView *) [mv dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];


    if (!pinView)
    {
        pinView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];

       pinView.canShowCallout = YES;

       //Here, just initialize a blank UIImageView ready to use.
       //Set image below AFTER we have a dequeued or new view ready.
       UIImageView *houseIconView = [[UIImageView alloc] init];
       [houseIconView setFrame:CGRectMake(0, 0, 30, 30)];
       pinView.leftCalloutAccessoryView = houseIconView;
    }
    else
    {
        pinView.annotation = annotation;
    }

    //At this point, we have a dequeued or new view ready to use
    //and pointing to the correct annotation.
    //Update image on the leftCalloutAccessoryView here
    //(not just when creating the view otherwise an annotation
    //that gets a dequeued view will show an image of another annotation).

    UIImageView *houseIconView = (UIImageView *)pinView.leftCalloutAccessoryView;
    NSString *saImageName = sa.whichSandwich.imageName;
    UIImage *houseIcon = [UIImage imageNamed: saImageName];

    if (houseIcon == nil) {
        //In case the image was not found,
        //set houseIcon to some default image.
        houseIcon = someDefaultImage;
    }

    houseIconView.image = houseIcon;

    return pinView;

}