如何从通过MKAnnotationView添加的按钮获取单击事件

时间:2011-08-04 12:12:36

标签: iphone ios objective-c uibutton mkmapview

任何人都知道是否有办法从添加到button的{​​{1}}获取点击事件,此MKAnnotationView用作标签,仅显示每个针脚的名称button,现在我在点击map时成功显示自定义view(包含图片,文字......),所以我需要在按钮时执行相同的操作(标签)被点击。

感谢您提供任何建议。

pinbutton的代码:

MKAnnotationView

3 个答案:

答案 0 :(得分:16)

标准UI方法是使用标注视图并在progrmr显示时添加附件按钮。

但是,如果您必须直接向MKAnnotationView添加按钮,那么您的方法存在的问题是MKPinAnnotationView的默认框架(无法轻易更改)小于您添加的按钮,因此大多数按钮都不会响应触摸,即使您切换到使用MKAnnotationView并增加帧大小,MKMapView也会阻止按钮进行任何触摸。< / p>

您需要做的是在按钮上添加UITapGestureRecognizer(使用手势处理程序的操作方法而不是按钮上的addTarget)并将按钮添加到普通MKAnnotationView适当的帧大小而不是MKPinAnnotationView

示例:

- (MKAnnotationView *)mapView:(MKMapView *)mapView 
        viewForAnnotation:(id<MKAnnotation>)annotation
{
    MKAnnotationView *annView = (MKAnnotationView *)[mapView 
            dequeueReusableAnnotationViewWithIdentifier: @"pin"];
    if (annView == nil)
    {
        annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation 
                      reuseIdentifier:@"pin"] autorelease];

        annView.frame = CGRectMake(0, 0, 200, 50);

        UIButton *pinButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        pinButton.frame = CGRectMake(0, 0, 140, 28);
        pinButton.tag = 10;

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] 
            initWithTarget:self action:@selector(handlePinButtonTap:)];
        tap.numberOfTapsRequired = 1;
        [pinButton addGestureRecognizer:tap];
        [tap release];

        [annView addSubview:pinButton]; 
    }

    annView.annotation = annotation;

    UIButton *pb = (UIButton *)[annView viewWithTag:10];
    [pb setTitle:annotation.title forState:UIControlStateNormal];

    return annView;
}

- (void) handlePinButtonTap:(UITapGestureRecognizer *)gestureRecognizer 
{
    UIButton *btn = (UIButton *) gestureRecognizer.view;
    MKAnnotationView *av = (MKAnnotationView *)[btn superview];
    id<MKAnnotation> ann = av.annotation;
    NSLog(@"handlePinButtonTap: ann.title=%@", ann.title);
}


请注意,这将阻止映射视图的didSelectAnnotationView委托方法触发。如果您需要触发该方法(在添加到按钮的手势处理程序方法中),则添加以下内容:

//in the view controller's interface:
@interface YourVC : UIViewController <UIGestureRecognizerDelegate>

//where the UITapGestureRecognizer is created:
tap.delegate = self;

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
        shouldRecognizeSimultaneouslyWithGestureRecognizer
            :(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

答案 1 :(得分:3)

我使用此代码在标注视图(在我的应用中)添加了一个按钮(为了清晰起见,已减少):

-(MKAnnotationView *)mapView:(MKMapView *)map 
        viewForAnnotation:(StationItem*)annotation
{
    static NSString *AnnotationViewID = @"stationViewId";

    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;  // use default user location view
    }

    MKPinAnnotationView *annotationView = 
        (MKPinAnnotationView*) [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];

    if (annotationView == nil) {
        // if an existing pin view was not available, create one
        annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];

        // add rightAccessoryView
        UIButton* aButton = [UIButton buttonWithFrame:CGRectMake(0, 0, 75, 30)];
        [aButton setTitle:@"Directions" forState:UIControlStateNormal];
        annotationView.rightCalloutAccessoryView = aButton;
    }

    annotationView.annotation = annotation;
    annotationView.canShowCallout = YES;
    annotationView.animatesDrop   = NO;

    return annotationView;
}

执行此操作后,您需要实现MKMapViewDelegate以在点击按钮时处理对委托的回调:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control

答案 2 :(得分:-1)

尝试将触摸传递给子视图:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 [pinButton touchesEnded:touches withEvent:event];
}

如果你的buttonView在前面,我很惊讶你有问题吗?尝试确保它是: [self bringSubviewToFront:pinButton];