如何从通过MKAnnotationView添加的button获取点击事件

任何人都知道是否有一种方法可以通过添加到MKAnnotationViewbutton来获取点击事件,这个button被用作标签来显示map上每个图钉的名字,现在我成功地显示了一个自定义view (包含图像,文本….)当点击的pin ,所以我需要做同样的事情,当button(标签)被点击。

感谢您提供的任何build议。

MKAnnotationView button代码:

 UIButton * pinButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 140, 28)]; [pinButton.titleLabel setTextColor:[UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1]]; [pinButton setCenter:CGPointMake(pinAnnotationView.center.x + 70, pinAnnotationView.center.y + 10)]; [pinButton addTarget:self action:@selector(pinLabelClicked) forControlEvents:UIControlEventTouchUpInside]; [pinAnnotationView addSubView:pinButton]; [pinButton setUserInteractionEnabled:YES]; 

标准的用户界面方法是使用标注视图,并添加一个附件button,如progrmr显示。

但是,如果您必须直接向MKAnnotationView添加一个button,那么您的方法存在的问题是MKPinAnnotationView的默认框架(不易更改)比您添加的button更小,因此大多数button将会不响应触摸,即使您切换到使用MKAnnotationView并增加帧大小, MKMapView将阻止button获得任何接触。

你需要做的是将UITapGestureRecognizer添加到button(使用手势处理程序的操作方法,而不是button上的MKAnnotationView ),并将该button添加到具有适当框架大小的普通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委托方法触发。 如果您需要触发此方法( 除了button的手势处理程序方法),请添加以下内容:

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

我使用下面的代码在标注视图中添加了一个button(在我的应用程序中)(为了清晰起见,缩小了):

 -(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处理callback委托当点击button:

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

尝试通过触摸到子视图:

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

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