0

有没有办法改变 MKAnnotationView 样式(比如从带有数字的红色标签到带有数字的绿色标签)。

我想根据与目标的距离来改变这种风格。我的注释随着用户一起移动。

我不想使用删除/添加注释,因为它会导致“闪烁”。可以以某种方式完成吗?

更新

我正在添加代码,我现在是怎么做的

MKAnnotationView *av = [mapView viewForAnnotation:an];

if ([data->type isMemberOfClass:[UserAnnotationImage class]])
{
    UIImage *img = [UIImage imageNamed: ((UserAnnotationImage *)data->type)->url];
    [av setImage:img];
}
else if ([data->type isMemberOfClass:[UserAnnotationLabel class]])
{

    UIView * v = [av viewWithTag:0];
    v = ((UserAnnotationLabel *)data->type)->lbl;

    av.frame = ((UserAnnotationLabel *)data->type)->lbl.frame;
}
else if ([data->type isMemberOfClass:[UserAnnotationView class]])
{

    UIView * v = [av viewWithTag:0];
    v = ((UserAnnotationView *)data->type)->view;
    av.frame = ((UserAnnotationView *)data->type)->view.frame;
}

可悲的是,它不起作用:(

4

1 回答 1

4

是的,基本上你得到一个注解视图的引用并直接更新它的内容。

另一种方法,如果你有一个自定义的注解视图类,是让注解视图监控它感兴趣的变化(或者有一些外部的东西告诉它)并更新自己。

如果您使用普通的MKAnnotationViewMKPinAnnotationView.

无论您在哪里检测到需要对视图进行更改,都可以通过调用地图视图的viewForAnnotation 实例方法来获取对视图的引用。这与调用viewForAnnotation委托方法不同。

获得对视图的引用后,您可以根据需要进行修改,并且更改应立即出现。

重要的一点是,您用于更新委托方法之外的视图的逻辑与您在viewForAnnotation委托方法中的逻辑必须匹配。这是因为地图视图稍后可能会调用委托方法(在您手动更新视图之后),并且当它调用时,那里的代码应该考虑更新的数据。

最好的方法是将注释视图构造代码放在一个由委托方法调用的公共方法中,并在其中手动更新视图。

有关仅更新注释视图的示例,请参阅从 MKMapView 中的 MKAnnotation 更改 UIImageimage

有关使用自定义注释视图类更新视图的示例(主要是一种方法的想法),请参阅iPad Mapkit - Change title of "Current Location"定期更新视图的引脚颜色(绿色、紫色、红色、绿色、紫色、红色等)。


您的代码中有太多未知数,无法解释为什么它不起作用。例如:

  • 是什么data?它是特定于注释的(是否与 相关an)?是什么type?将注记添加到地图后是否会发生变化?
  • 为什么要data存储整个视图对象,例如 a UILabelorUIView而不是您要在这些视图中显示的基础数据?
  • imageNamed要求图像是项目中的资源(不是任意 url)
  • 不要使用标签0(这是所有视图的默认设置)。从 开始编号1
  • 您使用 viewWithTag 获得一个视图,然后立即将其替换为另一个视图。


相反,我将给出一个更详细但更简单(r)的示例......

MKAnnotation假设您有一个具有以下属性(除了坐标、标题和副标题)的注释类(实现的类):

@property (nonatomic, assign) BOOL haveImage;
@property (nonatomic, copy) NSString *labelText;
@property (nonatomic, copy) NSString *imageName;
@property (nonatomic, assign) CLLocationDistance distanceFromTarget;

为了解决上面提到的“重点”(viewForAnnotation委托方法和视图更新代码应该使用相同的逻辑),我们将创建一个方法,该方法传递一个注释视图并根据注释的属性根据需要对其进行配置. viewForAnnotation然后,委托方法和注释属性更改时手动更新视图的代码都将调用此方法。

在这个例子中,我这样做是为了让注释视图显示图像,否则它会显示标签haveImageYES此外,标签的背景颜色基于distanceFromTarget

-(void)configureAnnotationView:(MKAnnotationView *)av
{
    MyAnnotationClass *myAnn = (MyAnnotationClass *)av.annotation;

    UILabel *labelView = (UILabel *)[av viewWithTag:1];

    if (myAnn.haveImage)
    {
        //show image and remove label...
        av.image = [UIImage imageNamed:myAnn.imageName];
        [labelView removeFromSuperview];
    }
    else
    {
        //remove image and show label...
        av.image = nil;

        if (labelView == nil)
        {
            //create and add label...
            labelView = [[[UILabel alloc] 
                initWithFrame:CGRectMake(0, 0, 50, 30)] autorelease];
            labelView.tag = 1;
            labelView.textColor = [UIColor whiteColor];
            [av addSubview:labelView];
        }

        if (myAnn.distanceFromTarget > 100)
            labelView.backgroundColor = [UIColor redColor];
        else
            labelView.backgroundColor = [UIColor greenColor];

        labelView.text = myAnn.labelText;
    }
}

viewForAnnotation委托方法如下所示:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation 
{
    if ([annotation isKindOfClass:[MyAnnotationClass class]])
    {
        static NSString *myAnnId = @"myann";
        MKAnnotationView *av = [mapView dequeueReusableAnnotationViewWithIdentifier:myAnnId];
        if (av == nil)
        {
            av = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:myAnnId] autorelease];
        }
        else
        {
            av.annotation = annotation;
        }

        [self configureAnnotationView:av];

        return av;
    }

    return nil;
}

最后,注解的属性发生变化的地方和你想要更新注解视图的地方,代码看起来像这样:

ann.coordinate = someNewCoordinate;
ann.distanceFromTarget = theDistanceFromTarget;
ann.labelText = someNewText;
ann.haveImage = YES or NO;
ann.imageName = someImageName;

MKAnnotationView *av = [mapView viewForAnnotation:ann];
[self configureAnnotationView:av];
于 2012-09-04T14:24:25.463 回答