MKPinAnnotationView 子视图不更新

Posted

技术标签:

【中文标题】MKPinAnnotationView 子视图不更新【英文标题】:MKPinAnnotationView subview doens't update 【发布时间】:2013-09-02 13:48:56 【问题描述】:

我正在开发一个使用自定义 AnnotationViews 的应用程序。它有一个自定义图像和一个带有标签的背景。背景和标签是annotationView的子视图。

if ([annotation isKindOfClass:[VehicleAnnotation class]]) 
    VehicleAnnotation *vehicleAnnotation = annotation;

    MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:driverAnnotationIdentifier];
    if(!pinView)
    
        pinView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:driverAnnotationIdentifier];
    

    pinView.annotation = annotation;

    pinView.canShowCallout = NO;
    pinView.image = [ImageHelper imageForStatus:vehicleAnnotation.vehicle.driver.driverStatus];

    // Add a label with the name of the driver
    CGRect pinFrame = pinView.frame;
    UILabel *label = [[UILabel alloc] init];
    [label setBackgroundColor:[UIColor clearColor]];
    [label setTextColor:[UIColor whiteColor]];
    [label setNumberOfLines:2];
    [label setLineBreakMode:NSLineBreakByWordWrapping];
    [label setFont:[UIFont systemFontOfSize:12]];
    label.text = vehicleAnnotation.vehicle.driver.description;

    CGSize maximumSize = CGSizeMake(100, 50);
    CGSize myStringSize = [label.text sizeWithFont:label.font
                                 constrainedToSize:maximumSize
                                     lineBreakMode:label.lineBreakMode];

    CGRect labelFrame = CGRectMake(pinFrame.origin.x, pinFrame.origin.y + pinFrame.size.height * 2 + 2, myStringSize.width, myStringSize.height);
    [label setFrame:labelFrame];

    // Add a background to the label.
    CGFloat offset = 5;
    CGRect backgroundFrame = CGRectMake(labelFrame.origin.x - offset, labelFrame.origin.y - offset , labelFrame.size.width + 2 * offset, labelFrame.size.height + 2 * offset);
    UIView *backgroundView = [[UIView alloc] initWithFrame:backgroundFrame];
    backgroundView.layer.cornerRadius = 5;
    backgroundView.layer.masksToBounds = YES;
    [backgroundView setBackgroundColor:[UIColor darkGrayColor]];
    [backgroundView setAlpha:0.8];
    [pinView addSubview:backgroundView];

    [label setUserInteractionEnabled:YES];
    [label setMultipleTouchEnabled:YES];
    [pinView addSubview:label];

    return pinView;

每次收到新职位时都会执行此代码。问题是旧标签和旧背景仍然存在。所以我坚持我把这段代码:

MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:driverAnnotationIdentifier];
if(!pinView)

    pinView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:driverAnnotationIdentifier];

for(UIView *view in [pinView subviews])

    [view removeFromSuperview];

pinView.annotation = annotation;

但是没有显示标签或背景。有人可以帮我以适当的方式替换或删除背景和标签吗?

谢谢!

【问题讨论】:

【参考方案1】:

我建议制作您自己的自定义 MKAnnotatinView。否则,使用上面的代码,尝试在你分配初始化 MKAnnotationView 的块内添加标签和背景视图。如下所示,为块外的不同注释设置框架和文本以及其他属性。

if ([annotation isKindOfClass:[VehicleAnnotation class]]) 
    VehicleAnnotation *vehicleAnnotation = annotation;

    MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:driverAnnotationIdentifier];
    if(!pinView)
    
        pinView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:driverAnnotationIdentifier];
    UILabel *label = [[UILabel alloc] init];
    [label setBackgroundColor:[UIColor clearColor]];
    [label setTextColor:[UIColor whiteColor]];
    [label setNumberOfLines:2];
    [label setLineBreakMode:NSLineBreakByWordWrapping];
    [label setFont:[UIFont systemFontOfSize:12]];
    [label setUserInteractionEnabled:YES];
    [label setMultipleTouchEnabled:YES];
    [label setTag:101];

    UIView *backgroundView = [[UIView alloc]init];
    [backgroundView setTag:102];
    backgroundView.layer.cornerRadius = 5;
    backgroundView.layer.masksToBounds = YES;
    [backgroundView setBackgroundColor:[UIColor darkGrayColor]];
    [backgroundView setAlpha:0.8];
    [pinView addSubView:backgroundView];
    [pinView addSubview:label];



    

    pinView.annotation = annotation;

    pinView.canShowCallout = NO;
    pinView.image = [ImageHelper imageForStatus:vehicleAnnotation.vehicle.driver.driverStatus];

    // set frame of Label
    CGRect pinFrame = pinView.frame;
   UILabel *label = (UILabel *)[pinView viewWithTag:101];
    label.text = vehicleAnnotation.vehicle.driver.description;

    CGSize maximumSize = CGSizeMake(100, 50);
    CGSize myStringSize = [label.text sizeWithFont:label.font
                                 constrainedToSize:maximumSize
                                     lineBreakMode:label.lineBreakMode];

    CGRect labelFrame = CGRectMake(pinFrame.origin.x, pinFrame.origin.y + pinFrame.size.height * 2 + 2, myStringSize.width, myStringSize.height);
    [label setFrame:labelFrame];

    // set backgroundView frame.
    CGFloat offset = 5;
    CGRect backgroundFrame = CGRectMake(labelFrame.origin.x - offset, labelFrame.origin.y - offset , labelFrame.size.width + 2 * offset, labelFrame.size.height + 2 * offset);
    UIView *backgroundView = [pinView viewWithTag:102];
    [backgroundView setFrame:backgroundFrame];

    return pinView;

【讨论】:

这段代码不断发生同样的事情。当它启动时,它显示背景(没有标签......)并且在更新时不再显示背景。我想唯一的解决方案是自定义 MKPinAnnotationView 是的,对不起,我首先添加了标签作为子视图,而不是背景视图。我已经修复了代码,检查这是否有帮助,否则自定义注释是你的答案。@Michael90 标签现在显示正确,但更新后标签和背景都消失了。我会将您的回答标记为已接受,因为我相信自定义注释是可行的方法。【参考方案2】:

设置一个MKPinAnnotationView的image是无效的,它会覆盖它。使用常规的 MKAnnotationView。

另外在 Stackocerflow 上搜索,这个问题在您提出问题前六个小时就被问及并得到了回答。 MapView Custom Pin Image Issue

【讨论】:

这不是关于图像,而是关于添加子视图并更新它 代码的第 12 行尝试设置 MKPinAnnotationView 的图像。我怀疑他们是相关的。本质上,MKPinAnnotationView 看起来像 Apple 想要的样子,如果你想要别的东西,那么你应该继承 MKAnnotationView。

以上是关于MKPinAnnotationView 子视图不更新的主要内容,如果未能解决你的问题,请参考以下文章

MKPinAnnotationView 不动

MKPinAnnotationView 红色图钉替换为图片

MKPinAnnotationView - 不同引脚的不同动作

MKPinAnnotationView 无法设置自定义图像

自定义 MKPinAnnotationView 颜色

MKPinAnnotationView 不显示标题