【问题标题】:mapView:viewForAnnotation: not called when delegate set in codemapView:viewForAnnotation:在代码中设置委托时未调用
【发布时间】:2013-03-29 13:29:20
【问题描述】:

我的 MKAnnotations 有一个自定义类,我想覆盖默认的 mapView:viewForAnnotatation 方法,以便在标注中添加额外信息。当我在代码中设置我的委托时(根据下面的代码),注释会被丢弃在地图上并且是可选择的,但我的 mapView:viewForAnnoation 永远不会被调用。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
    NSLog(@"viewForAnnotation: called");
    MKAnnotationView *aView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"mapPin"];
    if(!aView){
        aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"mapPin"];
    }
    aView.annotation = annotation;

    return aView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view.
    self.mapView.delegate = self;

}

我知道委托正在设置,因为我可以覆盖方法 -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view,并且当我选择注释时会看到 NSLog。

当我从在代码中设置委托更改为在情节提要中设置它时,会调用该方法(NSLog(@"viewForAnnotation: called"); 语句出现)但注释不会出现在地图上,有时会出现此错误出现:

<Error>: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedImageBlockData: bad readSession [0x8618480]

【问题讨论】:

    标签: iphone ios objective-c mapkit mkannotation


    【解决方案1】:

    这似乎是两个不同的问题:

    1. 关于代码 v 故事板中的设置委托,很难协调您的各种观察(委托方法 didSelectAnnotationView 在两种情况下都被调用,但 viewForAnnotation 不是)。在情节提要的代码 v 中设置它的唯一区别是设置 delegate 的时间。您没有向我们展示添加注释的过程,因此很难根据您的描述进行诊断。如果您的委托方法都没有被调用,我会怀疑 mapView IBOutlet,但如果有些正在工作而有些没有,我只能怀疑是时间问题。

    2. 关于MKAnnotationView 的设置,默认实现什么都不做。您要么需要编写自己的MKAnnotationView 子类,如果您使用自己的图像,则设置其图像,或者更简单,只需使用MKPinAnnotationView。但是仅仅创建一个MKAnnotationView 不会做任何事情。你真的想要:

      - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
          // If it's the user location, just return nil.
          if ([annotation isKindOfClass:[MKUserLocation class]])
              return nil;
      
          // Handle any custom annotations.
          MKAnnotationView *aView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"mapPin"];
          if(aView){
              aView.annotation = annotation;
          } else {
              aView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"mapPin"];
          }
      
          aView.canShowCallout = NO;
      
          return aView;
      }
      

      (注意,我不仅要创建MKPinAnnotationView,还要确保它不是MKUserLocation,以防您选择在地图上显示用户位置。我也要去显式设置canShowCallout,因为这大概就是您编写此方法的原因。)

    底线,如果你想显示一个简单的引脚注释视图,请使用MKPinAnnotationView。单独使用MKAnnotationView 将导致不会出现任何注释。

    【讨论】:

      【解决方案2】:

      如果其他人正在寻找在代码中设置委托时没有调用 mapView:viewForAnnotatation 的原因,则 iOS 6 中存在一个错误 - http://openradar.appspot.com/12346693

      【讨论】:

      • 谢谢,这救了我的命!
      【解决方案3】:

      我遇到了同样的问题,我想分享我的解决方案:

      我也覆盖

      (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation

      但我意识到这些注释的工作方式类似于 TableView,iOS 将像 TVC(表格视图控制器)中的单元格一样重用注释

      由于我只使用一个标识符mapView dequeueReusableAnnotationViewWithIdentifier:@"mapPin",因此如果内存中有足够的“注释”,则无需再次调用 ViewForAnnotation。

      所以我的解决方案是根据我的条件在第一次加载地图时创建多个标识符。

      这解决了我的问题。

      【讨论】:

        【解决方案4】:

        当我在寻找同样的问题时,我只是不小心掉到了这个问题上。

        我解决了我的问题,就我而言,我正在调整 mapview 的大小。 我在调整mapview 的大小后添加了delegate。它现在完美运行。!

        【讨论】:

          猜你喜欢
          • 2012-03-18
          • 1970-01-01
          • 1970-01-01
          • 2019-10-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-25
          • 1970-01-01
          相关资源
          最近更新 更多