【问题标题】:Refresh MKAnnotationView on a MKMapView在 MKMapView 上刷新 MKAnnotationView
【发布时间】:2010-12-14 06:12:23
【问题描述】:

我想为我的自定义 MKAnnotationView 同步加载图像;我已经在使用 EGOImageView 框架(它与 UITableViews 配合得很好),但我无法让它在 MKMapView 上工作。图片似乎已加载,但我无法在地图上刷新它们 - [myMap setNeedsDisplay] 什么都不做。

【问题讨论】:

    标签: iphone cocoa-touch refresh mkmapview


    【解决方案1】:

    感谢@Vladimir 的帮助!你的回答启发了我的回答。 我做了一些更改以使其更清晰。

    func addAnnotation(coordinate: CLLocationCoordinate2D) {
        let annotation = Annotation()
        annotation.coordinate = coordinate
        annotations.append(annotation)
        mapView.addAnnotation(annotation)
        for index in 0..<annotations.count {
            if let view = mapView.view(for: annotations[index]) as? AnnotationView {
                if index == 0 {
                    view.imageView.image = NSImage(named: "icon_positioning")
                } else {
                    view.imageView.image = NSImage(named: "icon_positioning")
                }
            }
        }
    }
    

    MKMapview中的协议也需要实现:

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let view = mapView.dequeueReusable(withClass: AnnotationView.self, annotation: annotation)
        if index == 0 {
            view.imageView.image = NSImage(named: "icon_positioning")
        } else {
            view.imageView.image = NSImage(named: "icon_positioning")
        }
        return view
    }
    

    顺便说一下,这里的AnnotationView初始化是:

    public extension MKMapView {
        func dequeueReusable<T: MKAnnotationView>(withClass name: T.Type,annotation: MKAnnotation?) -> T {
            if let view = dequeueReusableAnnotationView(withIdentifier: T.identifier()) as? T {
                return view
            }
            let view = T.init(annotation: annotation, reuseIdentifier: T.identifier())
            return view
        }
    }
    

    再次感谢@Vladimir 的回答

    【讨论】:

      【解决方案2】:

      我想用新选择的头像刷新用户位置图钉。我为这种情况找到了另一种快速解决方案。我有2个屏幕。第一个用于选择头像,第二个用于在地图上显示用户。

      斯威夫特 5 您可以通过创建 MKAnnotationView

      来更改用户位置图像
      func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
      
          if annotation is MKUserLocation {
              let userIdentifier = "UserLocation"
              var userView = mapView.dequeueReusableAnnotationView(withIdentifier: userIdentifier)
              if userView == nil {
                  userView = MKAnnotationView(annotation: annotation, reuseIdentifier: userIdentifier)
              } else {
                  userView?.annotation = annotation
              }
      
              userView!.image = UIImage(named: "avatar1") //your image
      
              return userView
          }
      
          return nil
       }
      

      因此,如果用户将头像更改为其他内容,例如“avatar2”,它将不会刷新。

      为了刷新用户位置图像,我在 viewWillAppear()

      中添加了此代码
       self.mapView.showsUserLocation = false
       self.mapView.showsUserLocation = true
      

      【讨论】:

        【解决方案3】:

        (我不知道如何表明这篇文章与 zerodiv 的答案有关。)我能够通过添加各种 kickstart 来让 zerodiv 的方法工作,强制一个无意义但不同的坐标,然后恢复先前的正确的一。由于第一个位置,屏幕根本不闪烁。

        CLLocationCoordinate2D center = mapView.centerCoordinate; 
        CLLocationCoordinate2D forceChg;
        forceChg.latitude = 0;
        forceChg.longitude = curLongNum;
        
        mapView.centerCoordinate = forceChg;
        mapView.centerCoordinate = center;
        

        【讨论】:

        • 如果我对区域更改有一些操作怎么办?
        【解决方案4】:

        这对我有用

        #import "EGOImageView.h"
        
        - (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
        {
            //ENTER_METHOD;    
            if([annotation isKindOfClass:[MKUserLocation class]]) return nil;  
            MKPinAnnotationView *annView;
        
            static NSString *reuseIdentifier = @"reusedAnnView";
            annView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
            annView.canShowCallout = YES;
            annView.calloutOffset = CGPointMake(-5.0f, 0.0f);
            annView.opaque = NO;
            annView.image = [[UIImage imageNamed:@"tempImage.png"] retain];
        
            YourModel *p = annotation; // make this conform to <MKAnnotation>
            EGOImageView *egoIV = [[EGOImageView alloc] initWithPlaceholderImage:[UIImage imageNamed:@"tempImage.png"]];
            [egoIV setDelegate:self];
            egoIV.imageURL = [NSURL URLWithString:p.theUrlToDownloadFrom];
            [annView addSubview:egoIV];
            [egoIV release];
        
        
            return [annView autorelease];
        }
        

        【讨论】:

          【解决方案5】:

          我发现只有一种可靠的方法来更新注释,其他方法对我不起作用:只是删除并再次添加注释:

          id <MKAnnotation> annotation;
          
          // ...
          
          [mapView removeAnnotation:annotation];
          [mapView addAnnotation:annotation];
          

          此代码将使 -[mapView:viewForAnnotation:] 再次被调用,因此您的注释视图将被再次创建(或者如果您使用 dequeueReusableAnnotationViewWithIdentifier 则可能被重用)并具有正确的数据。

          【讨论】:

          • 我最终使用这种技术来刷新单个注释
          • 我正在尝试使用这种方法,并且希望它能够工作,但它似乎并不可靠,具体取决于缩放级别。有时,图钉向左/向右偏移太多,标注不再对齐。 (这是指具有细微变化但在其他方面构成相同的图钉图像,图钉“中心”位于图像的最中心。)嗯 ...
          • 是的,我不得不再次繁琐地添加注释来刷新它们。
          • 如果你想更新一个选中的注解是不行的
          【解决方案6】:

          这是我发现强制重绘 MKAnnotationViews 的唯一方法:

          // 强制更新地图视图(否则注释视图不会重绘)

          CLLocationCoordinate2D center = mapView.centerCoordinate;

          mapView.centerCoordinate = 中心;

          看似无用,但确实有效。

          【讨论】:

          • 对我也不起作用。如果会的话,那就太奇怪了。
          • 不好的方法,因为例如我有一些基于当前区域的操作,您建议以编程方式更改此区域
          【解决方案7】:

          我自己没有尝试过,但它可能会起作用:
          使用 MKMapView - (MKAnnotationView *)viewForAnnotation:(id &lt;MKAnnotation&gt;)annotation 方法获取注释视图并为其设置新图像。

          编辑:我自己尝试过,这种方法对我来说效果很好:

          //  Function where you got new image and want to set it to annotation view
          for (MyAnnotationType* myAnnot in myAnnotationContainer){
              MKAnnotationView* aView = [mapView viewForAnnotation: myAnnot];
              aView.image = [UIImage imageNamed:@"myJustDownloadedImage.png"];
          }
          

          调用此方法后,所有注释图像均已更新。

          【讨论】:

          • 现在就是这样。但是这种方式图像是同步加载的。
          • 如果您在图像加载后调用它并将此图像设置为视图 - 它不起作用吗?
          • 这就是问题 - 以后如何设置此图像。通过这样做,图像不会在 MKAnnotationView 上更新
          • 正如我所写 - MKMapView 允许您获取任何注释的视图。请参阅编辑后的答案如何使用它。
          • 我试过了,但标注不再位于图钉顶部的中心,即使图钉的位置与上一张图片相同。放大后似乎加剧了。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-19
          • 1970-01-01
          • 2012-02-28
          • 2010-12-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多