ios MKMapView MKPointAnnotation 点击事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15292318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MKMapView MKPointAnnotation tap event
提问by Ravi Vooda
I have a list of annotations (MKPointAnnotation). I have a UIViewController which is for the whole view, MKMapView implementing Controller, which I thought is useful for detecting the users interaction with the map, my own MKPointAnnotation implementing (subclass) Controller which tells how to show the annotation.
我有一个注释列表 (MKPointAnnotation)。我有一个用于整个视图的 UIViewController,MKMapView 实现控制器,我认为它对于检测用户与地图的交互很有用,我自己的 MKPointAnnotation 实现(子类)控制器告诉如何显示注释。
However I'm struck at the detection of the tap event by the user.
但是,我对用户检测到的点击事件感到震惊。
Googling told me that I have to do something by implementing the following function.
谷歌搜索告诉我,我必须通过实现以下功能来做一些事情。
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
and also that I have to implement this in some class which implements the MapViewDelegate (Protocol).
并且我必须在一些实现 MapViewDelegate(协议)的类中实现它。
But I'm all confused and unable to move forward. Can anyone tell me where to do what?
但我整个人都迷糊了,无法前进。谁能告诉我在哪里做什么?
Sorry for all the fuss!
对不起所有的大惊小怪!
回答by Rob
There are two ways of detecting user interaction with your annotation view. The common technique is to define a callout (that standard little popover bubble that you see when you tap on a pin in a typical maps app) for your MKAnnotationView
. And you create the annotation view for your annotation in the standard viewForAnnotation
method:
有两种方法可以检测用户与注释视图的交互。常用的技术是为您的MKAnnotationView
. 并且您在标准viewForAnnotation
方法中为您的注释创建注释视图:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
By doing this, you get a callout, but you're adding an right accessory, which is, in my example above, a disclosure indicator. That way, they tap on your annotation view (in my example above, a pin on the map), they see the callout, and when they tap on that callout's right accessory (the little disclosure indicator in this example), your calloutAccessoryControlTapped
is called (in my example below, performing a segue to some detail view controller):
通过这样做,你会得到一个标注,但你正在添加一个正确的配件,在我上面的例子中,这是一个披露指示器。这样,他们点击您的注释视图(在我上面的示例中,地图上的图钉),他们会看到标注,并且当他们点击该标注的右侧附件(本示例中的小显示指示器)时,您calloutAccessoryControlTapped
被称为(在我下面的示例中,对某个细节视图控制器执行转场):
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
[self performSegueWithIdentifier:@"DetailsIphone" sender:view];
}
That's a very typical user experience on the small iPhone screen.
这是 iPhone 小屏幕上非常典型的用户体验。
But, if you don't like that UX and you don't want the standard callout, but rather you want something else to happen, you can define your MKAnnotationView
so that a callout is not shown, but instead you intercept it and do something else (for example, on iPad maps apps, you might show some more sophisticated popover rather than the standard callout). For example, you could have your MKAnnotationView
not show a callout:
但是,如果您不喜欢该 UX 并且您不想要标准标注,而是希望发生其他事情,则可以定义您MKAnnotationView
的标注以便不显示标注,而是拦截它并执行其他操作(例如,在 iPad 地图应用程序上,您可能会显示一些更复杂的弹出窗口而不是标准标注)。例如,您可以MKAnnotationView
不显示标注:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
annotationView.canShowCallout = NO;
return annotationView;
}
But you can then manually handle didSelectAnnotationView
to detect when a user tapped on your MKAnnotationView
, in this example showing a popover:
但是您可以手动处理didSelectAnnotationView
以检测用户何时点击您的MKAnnotationView
,在此示例中显示了一个弹出窗口:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
[mapView deselectAnnotation:view.annotation animated:YES];
DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"];
controller.annotation = view.annotation;
self.popover = [[UIPopoverController alloc] initWithContentViewController:controller];
self.popover.delegate = self;
[self.popover presentPopoverFromRect:view.frame
inView:view.superview
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
I include some screen snapshots for the user interface yielded by the above code in my answer here.
我在此处的回答中包含了由上述代码生成的用户界面的一些屏幕快照。
回答by RhodanV5500
Robs example for Swift 3:
Swift 3 的 Robs 示例:
class MapViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
// Create map view in storyboard
view.delegate = self
}
}
extension MapViewController: MKMapViewDelegate
{
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
{
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView")
annotationView.canShowCallout = true
annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure)
return annotationView
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
{
guard let annotation = view.annotation else
{
return
}
let urlString = "http://maps.apple.com/?sll=\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)"
guard let url = URL(string: urlString) else
{
return
}
UIApplication.shared.openURL(url)
}
}
回答by Bajaj
Add button in this method
在此方法中添加按钮
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.canShowCallout = YES;
}
Then callout method
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
InfoView *infoView = [[InfoView alloc]initWithNibName:@"InfoView" bundle:nil];
[self.navigationController pushViewController:infoView animated:YES];
}