如何从通过MKAnnotationView添加的button获取点击事件
任何人都知道是否有一种方法可以通过添加到MKAnnotationView
的button
来获取点击事件,这个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];