我有一个地图视图,可以添加或多或少的注释:
- (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:
(自我)。不过,我最近意识到你也可以点击标注上的其他任何地方,并且会触发相同的两种方法。
使用UIButtonTypeDetailDisclosure
类型的按钮会发生这种情况,但UIButtonTypeCustom
按钮似乎不会发生这种情况。当没有附件视图时点击标注时,也不会触发委托方法。 (当然,这种行为并不令人惊讶;令人惊讶的是,如果附件视图是详细信息泄露按钮,则无论您是点击按钮本身还是只是某处,都会触发这两种方法 其他在标注中。)
我想摆脱标注中的按钮 - 或者至少用显示我自己的图像而不是股票“i”图标的按钮替换它 - 同时仍然允许用户点击标注上的任何位置触发我的行动。这可能吗?我没有看到与“callout tapped”对应的MKMapViewDelegate
方法。
答案 0 :(得分:29)
尝试在不更改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];
答案 1 :(得分:9)
要在用户点击“注释”视图后点按标注按钮,请在UITapGestureRecognizer
中添加didSelectAnnotationView
。通过这种方式,您可以在不需要附件视图的情况下实现对标注的点击。
然后,您可以从发件人处获取注释对象以进行进一步操作。
- (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];
}
}
答案 2 :(得分:7)
func mapView(mapView: MKMapView, didSelectAnnotationView view:MKAnnotationView) {
let tapGesture = UITapGestureRecognizer(target:self, action:#selector(calloutTapped(sender:)))
view.addGestureRecognizer(tapGesture)
}
func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView) {
view.removeGestureRecognizer(view.gestureRecognizers!.first!)
}
func calloutTapped(sender:UITapGestureRecognizer) {
let view = sender.view as! MKAnnotationView
if let annotation = view.annotation as? MKPointAnnotation {
performSegue(withIdentifier: "annotationDetailSegue", sender: annotation)
}
}
答案 3 :(得分:3)
如果您不需要点击指示,我建议您在创建时将UITapGestureRecognizer
投入到标注中,并将您的处理对象(可能是控制器)添加为具有适当操作的目标。
答案 4 :(得分:0)
- (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;
}
}