注釈のリストがあります(MKPointAnnotation)。ビュー全体のUIViewController、MKMapViewを実装するController、ユーザーがマップと対話するのを検出するのに役立つと考えているUIViewController、MKPointAnnotationを実装する(サブクラス)Controllerがあり、注釈の表示方法を示します。
ただし、ユーザーによるタップイベントの検出には驚かされます。
グーグルは、次の機能を実装することで何かをしなければならないと言った。
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
また、MapViewDelegate(プロトコル)を実装するクラスでこれを実装する必要があります。
しかし、私はすべて混乱しており、前進することができません。誰が何をすべきか教えてもらえますか?
大騒ぎしてすみません!
注釈ビューでのユーザーの操作を検出する方法は2つあります。一般的な手法は、MKAnnotationView
のコールアウト(通常のマップアプリでピンをタップしたときに表示される標準の小さなポップオーバーバブル)を定義することです。そして、標準のviewForAnnotation
メソッドで注釈の注釈ビューを作成します。
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
これを行うと、吹き出しが表示されますが、正しいアクセサリを追加します。これは、上記の例では開示インジケータです。こうすると、アノテーションビュー(上の例では地図上のピン)をタップしてコールアウトを表示し、そのコールアウトの適切なアクセサリ(この例では小さな開示インジケーター)をタップすると、calloutAccessoryControlTapped
が呼び出されます(以下の例では、詳細ビューコントローラーにセグエを実行します)。
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
[self performSegueWithIdentifier:@"DetailsIphone" sender:view];
}
これは、小さなiPhone画面での非常に典型的なユーザーエクスペリエンスです。
ただし、そのUXが気に入らず、標準のコールアウトが望ましくないが、何か他のことをしたい場合は、コールアウトが表示されないようにMKAnnotationView
を定義できますが、代わりにインターセプトして何か他の操作を行います(たとえば、iPadマップアプリでは、標準のコールアウトではなく、より洗練されたポップオーバーを表示できます)。たとえば、MKAnnotationView
にコールアウトを表示しないようにすることができます。
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
annotationView.canShowCallout = NO;
return annotationView;
}
しかし、その後、手動でdidSelectAnnotationView
を処理して、ユーザーがMKAnnotationView
をタップしたことを検出できます。この例では、ポップオーバーを示しています。
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
[mapView deselectAnnotation:view.annotation animated:YES];
DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"];
controller.annotation = view.annotation;
self.popover = [[UIPopoverController alloc] initWithContentViewController:controller];
self.popover.delegate = self;
[self.popover presentPopoverFromRect:view.frame
inView:view.superview
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
my answer here に、上記のコードによって生成されたユーザーインターフェイスの画面スナップショットをいくつか含めます。
Swift 3:のロブの例:
class MapViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
// Create map view in storyboard
view.delegate = self
}
}
extension MapViewController: MKMapViewDelegate
{
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
{
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView")
annotationView.canShowCallout = true
annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure)
return annotationView
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
{
guard let annotation = view.annotation else
{
return
}
let urlString = "http://maps.Apple.com/?sll=\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)"
guard let url = URL(string: urlString) else
{
return
}
UIApplication.shared.openURL(url)
}
}
このメソッドの追加ボタン
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.canShowCallout = YES;
}
Then callout method
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
InfoView *infoView = [[InfoView alloc]initWithNibName:@"InfoView" bundle:nil];
[self.navigationController pushViewController:infoView animated:YES];
}