web-dev-qa-db-ja.com

iOS 8 MKAnnotationView rightCalloutAccessoryView misaligned

私はまだiOSのことを一般にかなり新しいので、iOS 8との互換性についてアプリをテストしているときに問題を発見しました。 iOS 7ではすべてが正常に機能しましたが、iOS 8では、特定の状況下でrightCalloutAccessoryViewの位置がずれています。

最初のスクリーンショット:正しく配置 Correctly aligned

2番目のスクリーンショット:間違った配置 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 Betaセクションにもこの質問を追加しました: https://devforums.Apple.com/thread/242282?tstart=

ここまたはApple.developer.comで回答が得られた場合は、両方のサイトで見つけられるように反映します

38
byemute

これを解決するには、垂直方向のバグと水平方向のバグの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];
18
Meerschwein Bob

見た目は醜いですが、この問題の回避策を見つけることができました。

アクセサリビューの高さを吹き出しビューの高さと同じ値に設定します。私はハードコードされた値を使用しました:

  • iOS 7ターゲットの場合:45.0 px
  • iOS 8ターゲットの場合:54.0 px

(おそらく、デフォルトの注釈吹き出しビューの高さがiOS 7よりもiOS 8の方が大きいことに気づいたでしょう)。

あなたのコードでは、それは:

- (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;
}

また、これまでに見てきたことから、左側の両方のand右側のアクセサリビューを指定した場合、適切な値になるようにbothの高さを同じ値に設定する必要がありますアライメント。うまくいけば、この種のコードを書かないように、この問題は後続のiOSリリースで修正されるでしょう...

10
octy

こんにちは私はここでまったく同じ問題を抱えていましたが、それを解決するために私がやったことです:

吹き出しビューが長すぎると、MKAnnotationのタイトルテキストの表示に問題があるようです。スクリーンショットからでも、タイトルが省略され、省略記号が追加されている場合にのみ問題が発生することがわかります。したがって、標準のMKAnnotationはビューを適切にレイアウトしておらず、これはiOS8のバグです。

それまでは、手順 here を実行して独自のカスタムコールアウトを作成できます。

これは必要以上の作業だと思ったので、タイトル文字列をトリミングして省略記号を追加し、省略記号がそれ自体を実行しないようにしました。 (理想的ではありませんが、迅速な解決策であり、テキストはとにかく切り捨てられます)

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

とりあえず、rightCalloutAccessoryViewを

pin.rightCalloutAccessoryView.frame = CGRectZero;

そして、まだ機能している注釈ビューをクリックします。右側にボタンはありません。 iOS7とiOS8でテストされていますが、iOS6については不明です。

0
kolyancz

私は、注釈を追加する前にマップビューのデリゲートを設定することで作業を開始しましたが、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];

私のために修正しました。アノテーションが追加されるときにデリゲートメソッドが呼び出されることに気づいたので、アノテーションを追加する前にデリゲートが設定されていないと、呼び出されません。

0

Swift 3:

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

私が気付いた好奇心の1つは、最初に表示される吹き出しがアクセサリビューを適切に位置合わせするが、その後の選択では位置合わせしないことでした。デキューされた注釈ビューを返す前に[view setNeedsLayout]への呼び出しを追加しましたが、すべてが再び適切に整列し始めました。

これにより多くの時間を費やすことなく、ビューの階層が変更されていないため、キューから取り出されたビューの再レイアウトがトリガーされていないことが私の推測ではあります。

この問題についてはレーダーを提出することを強くお勧めします。このような標準的な使用例では、回避策を実装する必要はありません。

編集:

これはまだ多くの場合により良いように見えますが、タイトルが切り捨てられるのに十分な長さの注釈でこの問題がまだ発生しています。

0
gyratory circus