MapKit更新标注图像

发布于 2024-11-18 03:34:40 字数 2604 浏览 3 评论 0原文

在异步请求完成并包含有关注释状态的信息后,我无法找到更新自定义 MKAnnotationView 图像的方法。到目前为止,我有这样的:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {

    static NSString *identifier = @"EstacionEB";   
    if ([annotation isKindOfClass:[EstacionEB class]]) {
        EstacionEB *location = (EstacionEB *) annotation;

        CustomPin *annotationView = (CustomPin *) [_mapita dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[CustomPin alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        } else {
            annotationView.annotation = annotation;
        }

        UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png", [location elStatus]]];

        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        annotationView.image = image;

        NSDictionary *temp = [[NSDictionary alloc] 
                              initWithObjects:[NSArray arrayWithObjects:annotationView, location, nil]
                              forKeys:[NSArray arrayWithObjects:@"view", @"annotation", nil]
                              ];
        //This array is synthesized and inited in my controller's viewDidLoad
        [self.markers setObject:temp forKey:location.eid];
        return annotationView;
    }

    return nil;    
}

稍后,我做了一个请求,并使用结果,一个 NSDictionary,我尝试执行以下操作,这向两个元素返回 null:

- (void)updateStation:(NSString *)eid withDetails:(NSDictionary *)details
{
    NSInteger free = [details objectForKey:@"free"];
    NSInteger parkings = [details objectForKey:@"parkings"];

    NSDictionary *storedStations = [self.markers objectForKey:eid];

    CustomPin *pin = [storedStations objectForKey:@"view"]; //nil
    EstacionEB *station = [referencia objectForKey:@"annotation"]; //nil as well

    [station setSubtitle:free];

    NSString *status;
    if( free==0 ){
        status = @"empty";
    } else if( (free.intValue>0) && (parkings.intValue<=3)  ){
        status = @"warning";
    } else {
        status = @"available";
    }
    UIImage * image = [UIImage imageNamed:[NSString imageWithFormat:@"%@.png", status]];
    pin.image = image;
}

这不会带来任何错误(假设我粘贴并引用了一切正确),但 NSMutableDictionary 应该包含我的自定义 MKAnnotationView 和 MKAnnotation,但即使我在请求完成之前将它们全部记录下来并且它显示正确,当请求完成时,就好像两个MKAnnotationView 和 MKAnnotation 不是我所期望的,因此,我无法修改注释来更改图像或更新注释视图。

任何想法将不胜感激!

I'm having a problem finding out the way to update a custom MKAnnotationView image after a asynchronous request completes with information about the status of the annotation. So far, I have this:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {

    static NSString *identifier = @"EstacionEB";   
    if ([annotation isKindOfClass:[EstacionEB class]]) {
        EstacionEB *location = (EstacionEB *) annotation;

        CustomPin *annotationView = (CustomPin *) [_mapita dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[CustomPin alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        } else {
            annotationView.annotation = annotation;
        }

        UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png", [location elStatus]]];

        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        annotationView.image = image;

        NSDictionary *temp = [[NSDictionary alloc] 
                              initWithObjects:[NSArray arrayWithObjects:annotationView, location, nil]
                              forKeys:[NSArray arrayWithObjects:@"view", @"annotation", nil]
                              ];
        //This array is synthesized and inited in my controller's viewDidLoad
        [self.markers setObject:temp forKey:location.eid];
        return annotationView;
    }

    return nil;    
}

A little after, I do a request and with the results, an NSDictionary, I'm trying to do the following, which returns null to both elements:

- (void)updateStation:(NSString *)eid withDetails:(NSDictionary *)details
{
    NSInteger free = [details objectForKey:@"free"];
    NSInteger parkings = [details objectForKey:@"parkings"];

    NSDictionary *storedStations = [self.markers objectForKey:eid];

    CustomPin *pin = [storedStations objectForKey:@"view"]; //nil
    EstacionEB *station = [referencia objectForKey:@"annotation"]; //nil as well

    [station setSubtitle:free];

    NSString *status;
    if( free==0 ){
        status = @"empty";
    } else if( (free.intValue>0) && (parkings.intValue<=3)  ){
        status = @"warning";
    } else {
        status = @"available";
    }
    UIImage * image = [UIImage imageNamed:[NSString imageWithFormat:@"%@.png", status]];
    pin.image = image;
}

This brings up no errors (assuming I pasted and traduced everything correctly), but the NSMutableDictionary that should contain both my custom MKAnnotationView and the MKAnnotation, but even when I log them all before the request completes and it appears correctly, when the request completes its as if both the MKAnnotationView and MKAnnotation are just not what I expected, and thus, I can't modify the annotations to change the image or update the annotation view.

Any ideas would be appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北城孤痞 2024-11-25 03:34:40

我不确定为什么您从标记数组中获取零值(特别是对于注释)。但是,我不建议像这样存储对注释视图的引用。

viewForAnnotation 委托方法可以在地图视图认为有必要时随时调用,并且视图对象可以从一次调用更改为下一次调用。由于您还对每个注释使用相同的重用标识符来重用注释视图,因此同一视图对象也有可能稍后被另一个注释重用。

相反,在 updateStation 中,我建议执行以下操作:

  • 循环遍历地图视图的 annotations 数组
  • 如果注释的类型为 EstacionEB,则 ,然后检查其是否eid 与正在更新的匹配,
  • 更新注释的 subTitleelStatus 属性(更新 elStatus 很重要,因为它使用了经过viewForAnnotation 委托方法来设置图像)
  • 通过调用地图视图的 viewForAnnotation: 实例方法获取注释的当前视图(这是 与委托方法 mapView:viewForAnnotation: 相同)
  • 更新视图的 image 属性

请参阅此其他相关问题了解类似示例。

I'm not sure why you're getting nil values from your markers array (especially for annotation). However, I don't recommend storing a reference to the annotation view like that.

The viewForAnnotation delegate method can get called by the map view any time it thinks it's necessary and the view object could change from one call to the next. Since you are also re-using annotation views using the same re-use identifier for each annotation, there's also the possibility that the same view object could be re-used for another annotation later.

Instead, in updateStation, I suggest the following:

  • loop through the map view's annotations array
  • if the annotation is of type EstacionEB, then check if its eid matches the one being updated
  • update the annotation's subTitle and elStatus properties (it's important to update elStatus because it's used by the viewForAnnotation delegate method to set the image)
  • get the annotation's current view by calling the map view's viewForAnnotation: instance method (this is not the same as the delegate method mapView:viewForAnnotation:)
  • update the image property of the view

See this other related question for a similar example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文