iOS 8 MKAnnotationView rightCalloutAccessoryView未对齐

时间:2014-08-25 11:11:56

标签: ios mapkit ios8 mkannotationview

我仍然对iOS的东西很新,并且在测试我们的App for iOS 8兼容性时发现了一个问题。 在iOS 7中一切正常,但在iOS 8上,rightCalloutAccessoryView在某些情况下未对齐。

第一个屏幕截图:正确对齐Correctly aligned

第二个屏幕截图:错误的对齐Wrong alignment

正如您所看到的,当InfoWindow具有较长的标题时会出现问题。但是在iOS 7上并非如此,我找不到任何提及这已经发生变化的事情了吗?

我试图理解为什么并找到解决方法,但找不到任何东西。 这可以自行解决,还是我们必须为Apple提出问题?

任何帮助/想法都会受到高度赞赏,因为我对此问题的反应过度。

添加MKAnnotationViews的代码

- (MKAnnotationView *)viewForStation:(id<MKAnnotation>)annotation {
      static NSString *stationIdentifier = @"stao";
      MKAnnotationView *annotationView = [self.mapView dequeueReusableAnnotationViewWithIdentifier:stationIdentifier];
      if (annotationView == nil) {
          annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation           reuseIdentifier:stationIdentifier];
          annotationView.image = [UIImage bundleImageNamed:PIN_IMAGE];
          annotationView.canShowCallout = YES;
          annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
      }
      return annotationView;
}

您可能感兴趣,我(刚才)也将此问题添加到apple.developer.com上的iOS 8测试版部分:https://devforums.apple.com/thread/242282?tstart=0

如果我在这里或在apple.developer.com上得到答案,我会反映它,以便我们可以在两个网站上找到它

7 个答案:

答案 0 :(得分:18)

我通过设置autoresizingmask来修复垂直bug和frame.size.width来解决这个问题

UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[infoButton setFrame:CGRectMake(0, 0, CGRectGetWidth(infoButton.frame)+10, CGRectGetHeight(infoButton.frame))];
[infoButton setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleTopMargin];
[annotationView setRightCalloutAccessoryView:infoButton];

答案 1 :(得分:10)

丑陋,但我确实找到了解决这个问题的方法。

将附件视图高度设置为等于标注视图高度的值。我使用了硬编码值:

  • 适用于iOS 7目标:45.0 px
  • 适用于iOS 8目标:54.0 px

(您可能已经注意到默认注释标注视图的高度在iOS 8中比在iOS 7中更高)。

在您的代码中,那将是:

- (MKAnnotationView *)viewForStation:(id<MKAnnotation>)annotation {
  static NSString *stationIdentifier = @"stao";
  MKAnnotationView *annotationView = [self.mapView dequeueReusableAnnotationViewWithIdentifier:stationIdentifier];
  if (annotationView == nil) {
      annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation 
                                                    reuseIdentifier:stationIdentifier];
      annotationView.image = [UIImage bundleImageNamed:PIN_IMAGE];
      annotationView.canShowCallout = YES;

      UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

      // N.B. In production code, you would need a more generic way to adjust 
      // height values instead of hard-coding values based on NSFoundationVersionNumber...

      CGFloat height = (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) ? 55.f : 45.f;

      detailButton.frame = CGRectMake(0.f, 0.f, 32.f, height);
      annotationView.rightCalloutAccessoryView = detailButton;
  }
  return annotationView;
}

另外,从我到目前为止看到的情况来看,如果你同时指定左右边的附件视图,你必须将两个的高度设置为相同的值得到适当的对齐。希望这个问题将在后续的iOS版本中修复,以避免编写这种代码......

答案 2 :(得分:3)

嗨,我遇到了同样的问题,这就是我要解决的问题:

似乎问题是Callout视图在显示MKAnnotation标题文本太长时会出现问题。即使从您的屏幕截图中,您也可以看到只有在截断标题并添加省略号时才会出现问题。所以标准的MKAnnotation没有正确地布局视图,这是iOS8中的一个错误。

同时您可以按照here步骤创建自己的自定义标注。

我认为这对于我需要的东西来说太多了,所以我只是修剪了标题字符串并添加了省略号以防止它试图自己做。 (不理想,但是是一个快速的解决方案,无论如何文本都会被截断)

if (locTitle.length > 15) 
{
    locTitle = [NSString stringWithFormat:@"%@...", [locTitle substringToIndex:14]];
}

答案 3 :(得分:0)

我注意到的一个好奇心是我要显示的第一个标注会正确对齐附件视图,但随后的选择不会。在返回出列的注释视图之前,我添加了对[view setNeedsLayout]的调用,所有内容都开始正常对齐。

如果不花更多的时间在这上面,我最好的猜测是,由于视图层次结构没有改变,因此已经出列的视图没有触发重新布局。

我强烈建议为此问题提交雷达。没有必要为这样的标准用例实现变通方法。

编辑:

虽然在许多情况下这似乎仍然更好,但我仍然遇到这个问题的注释,其标题足够长,可以被截断。

答案 4 :(得分:0)

目前,我正在使用

隐藏rightCalloutAccessoryView
pin.rightCalloutAccessoryView.frame = CGRectZero;

并单击Annotation View仍然有效,右侧没有按钮。 在iOS7和iOS8上测试,不确定iOS6。

答案 5 :(得分:0)

通过在添加注释之前设置我的地图视图的委托来让我工作,并且不必更改del中的任何内容。

从以下内容出发:

    self.mapView = [[MKMapView alloc] init];
    NGAAnnotation *annotation = [[NGAAnnotation alloc] init];
    annotation.coordinate = coordinates;
    annotation.title = self.project.name;

    [self.mapView addAnnotation:annotation];
    self.mapView.delegate = self;

要:

    self.mapView = [[MKMapView alloc] init];
    NGAAnnotation *annotation = [[NGAAnnotation alloc] init];
    annotation.coordinate = coordinates;
    annotation.title = self.project.name;

    self.mapView.delegate = self;
    [self.mapView addAnnotation:annotation];

为我修好了。我注意到在添加注释时会调用delegate方法,所以如果在添加注释之前未设置委托,则不会调用它。

答案 6 :(得分:0)

在Swift 3中:

let infoButton = UIButton(type: .detailDisclosure)
annotationView.rightCalloutAccessoryView = infoButton