web-dev-qa-db-ja.com

吹き出しアクセサリビューなしで、注釈吹き出しの任意の場所をタップできるようにする

私は多かれ少なかれ次のような注釈を追加するマップビューを持っています:

- (MKAnnotationView *)mapView:(MKMapView *)mapView
            viewForAnnotation:(id <MKAnnotation>) annotation
{
    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                                       reuseIdentifier:@"MKPinAnnotationView"];
    annotationView.canShowCallout = YES;

    UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [detailButton addTarget:self
                     action:@selector(handleButtonAction)
           forControlEvents:UIControlEventTouchUpInside];
    annotationView.rightCalloutAccessoryView = detailButton;

    return annotationView;
}

IOS 7では、これにより、吹き出しの右側に「i」アイコンが表示されます。アイコンをタップすると、mapView:annotationView:calloutAccessoryControlTapped:(デリゲート上)とhandleButtonAction:(自分自身上)がトリガーされます。ただし、最近、コールアウトの他の場所をタップすることもでき、同じ2つのメソッドが実行されることに気付きました。

これは、タイプUIButtonTypeDetailDisclosureのボタンで発生しますが、UIButtonTypeCustomボタンでは発生しないようです。アクセサリビューがまったくないときにコールアウトをタップしても、デリゲートメソッドは実行されません。 (もちろん、その動作は驚くべきことではありません。驚くべきことは、アクセサリビューが詳細開示ボタンの場合、これら2つのメソッドに関係なく実行されることです。ボタン自体をタップするのか、吹き出しのどこかをタップするのか。)

コールアウトのボタンを削除するか、少なくとも、ユーザーがコールアウトの任意の場所をタップしてアクションをトリガーできるようにしながら、ストックの「i」アイコンの代わりに自分の画像を表示するボタンに置​​き換えたい。これは可能ですか? 「コールアウトタップ」に対応するMKMapViewDelegateメソッドが表示されません。

19
bdesham

UIButtonTypeDetailDisclosureタイプを変更せずに、ボタンのカスタム画像を設定してみてください。

UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];        
[detailButton setImage:[UIImage imageNamed:@"icon"] forState:UIControlStateNormal];

IOS7以降の場合、この画像はデフォルトで色付けされます。元のアイコンを保持したい場合は、以下を使用してください

[[UIImage imageNamed:@"icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]

または、アイコンを完全に削除したい場合

[detailButton setImage:[UIImage new] forState:UIControlStateNormal];
29
vokilam

ユーザーが注釈ビューをクリックした後にコールアウトボタンをタップするには、UITapGestureRecognizerdidSelectAnnotationViewを追加します。このようにして、アクセサリビューを必要とせずに、吹き出しのタップを実装できます。

その後、さらにアクションを実行するために、送信者から注釈オブジェクトを取り戻すことができます。

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self  action:@selector(calloutTapped:)];
    [view addGestureRecognizer:tapGesture];
}

-(void)calloutTapped:(UITapGestureRecognizer *) sender
{
    NSLog(@"Callout was tapped");

    MKAnnotationView *view = (MKAnnotationView*)sender.view;
    id <MKAnnotation> annotation = [view annotation];
    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        [self performSegueWithIdentifier:@"annotationDetailSegue" sender:annotation];
    }
}
9
Dhanu A

タップ表示が必要ない場合は、作成時にUITapGestureRecognizerをコールアウトにスローし、適切なアクションでターゲットとして処理オブジェクト(おそらくコントローラー)を追加することをお勧めします。

3
Leon Deriglazov
- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    Park *parkAnnotation = (Park *)[view annotation];
    switch ([control tag]) {
        case 0: // left button
        {
            NSURL *url = [NSURL URLWithString:parkAnnotation.link];
            [[UIApplication sharedApplication] openURL:url];
        }
            break;

        case 1: // right button
        {
            // build a maps url. This will launch the Maps app on the hardware, and the Apple maps website in the simulator
            CLLocationCoordinate2D coordinate = self.locationManager.location.coordinate;
            NSString *url2 = [NSString stringWithFormat:@"http://maps.Apple.com/maps?saddr=%f,%f&daddr=%f,%f",coordinate.latitude,coordinate.longitude,parkAnnotation.location.coordinate.latitude,parkAnnotation.location.coordinate.longitude];

            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url2]];
        }
            break;

        default:
            NSLog(@"Should not be here in calloutAccessoryControlTapped, tag=%ld!",(long)[control tag]);
            break;
    }
}
0
phani