ios 自定义 MKAnnotationView 标注
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8018841/
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
Customize the MKAnnotationView callout
提问by Janak Nirmal
I want to create a custom MKAnnotationView callout as shown in this image. I have tested several solutions but they only allow customization of the left/right images and title/subtitle. Can anybody please give me some source code or tutorial link for it?
我想创建一个自定义的 MKAnnotationView 标注,如图所示。我已经测试了几种解决方案,但它们只允许自定义左/右图像和标题/副标题。任何人都可以给我一些源代码或教程链接吗?
Currently I am clueless. Please help.
目前我一无所知。请帮忙。
回答by Jano
I understand you want a pin with a custom callout.
我知道您想要带有自定义标注的图钉。
We can't create a custom callout, but we can create an annotation with a completely customized view. So the trick is to add a second annotation when the first is selected, and make the 2nd annotation view look like a callout bubble.
我们无法创建自定义标注,但我们可以创建具有完全自定义视图的注释。所以诀窍是在选择第一个注释时添加第二个注释,并使第二个注释视图看起来像一个标注气泡。
This is the solution posted by users djibouti33and jacob-jenningsin the answer: MKAnnotationView - Lock custom annotation view to pin on location updates, which in turn is based in a blog postfrom Asynchrony Solutions. For explanation purposes, here is some UML from a forked project:
这是用户djibouti33和jacob- jennings在答案中发布的解决方案:MKAnnotationView - Lock custom annotation view to pin on location updates,这又基于Asynchrony Solutions的博客文章。出于解释的目的,这里有一些来自分叉项目的 UML:
This is a big hack, but also the cleanest way I've seen to implement custom annotations.
这是一个很大的技巧,但也是我见过的实现自定义注释的最干净的方式。
Start with a NSObject "Content" class which has a coordinate, the class of the callout view to use (in the UML is AnnotationView, but you can create more and set them here), and a dictionary of random values with the title, photo url, etc. Use this class to initialize a MKAnnotation "Annotation" object.
从一个 NSObject "Content" 类开始,它有一个坐标,要使用的标注视图的类(在 UML 中是 AnnotationView,但你可以创建更多并在此处设置它们),以及一个带有标题、照片的随机值字典url 等。使用这个类来初始化一个 MKAnnotation “Annotation”对象。
#import <MapKit/MapKit.h>
@interface Content : NSObject
@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
// ...
@interface Annotation : NSObject <MKAnnotation, AnnotationProtocol>
-(id) initWithContent:(Content*)content;
// ...
The Annotation implements AnnotationProtocol to announce it wants to handle the creation of its own MKAnnotationView. That is, your MKMapViewDelegate should have code like this:
Annotation 实现 AnnotationProtocol 来宣布它想要处理它自己的 MKAnnotationView 的创建。也就是说,你的 MKMapViewDelegate 应该有这样的代码:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// if this is a custom annotation, delegate the implementation of the view
if ([annotation conformsToProtocol:@protocol(AnnotationProtocol)]) {
return [((NSObject<AnnotationProtocol>*)annotation) annotationViewInMap:mapView];
} else {
// else, return a standard annotation view
// ...
}
}
The view returned will be of type AnnotationView, which implements AnnotationViewProtocol to announce that it wants to handle selection/deselection. Therefore, in your map view controller, the methods mapView:didSelectAnnotationView: and mapView:didDeselectAnnotationView: should delegate in a similar way to what we saw before.
返回的视图将是 AnnotationView 类型,它实现 AnnotationViewProtocol 以宣布它要处理选择/取消选择。因此,在您的地图视图控制器中,方法 mapView:didSelectAnnotationView: 和 mapView:didDeselectAnnotationView: 应该以与我们之前看到的类似的方式进行委托。
When the annotation is selected, a second annotation (CalloutAnnotation) is added, which follows the same behaviour, but this time the view returned (CalloutView) is initialized from a XIB, and contains Core Graphics code (in BaseCalloutView) to animate and replicate a callout.
选择注释后,会添加第二个注释 (CalloutAnnotation),它遵循相同的行为,但这次返回的视图 (CalloutView) 是从 XIB 初始化的,并包含核心图形代码(在 BaseCalloutView 中)以动画和复制大喊。
The initializer of the CalloutView class:
CalloutView 类的初始值设定项:
- (id)initWithAnnotation:(CalloutAnnotation*)annotation
{
NSString *identifier = NSStringFromClass([self class]);
self = [super initWithAnnotation:annotation reuseIdentifier:identifier];
if (self!=nil){
[[NSBundle mainBundle] loadNibNamed:identifier owner:self options:nil];
// prevent the tap and double tap from reaching views underneath
UITapGestureRecognizer *tapGestureRecognizer = ...
}
return self;
}
To be able to push another view controller from the callout view I used notifications.
为了能够从标注视图推送另一个视图控制器,我使用了通知。
The SO answer I linked at the top contains two complete projects implementing this code (class names may differ). I have another project using the UML above at https://github.com/j4n0/callout.
我在顶部链接的 SO 答案包含两个实现此代码的完整项目(类名可能不同)。我在https://github.com/j4n0/callout 上有另一个使用 UML 的项目。
回答by Mahesh
I added custom UIButton in MKAnnotationView. And on click of that button I have shown popOver with rootViewController with the view similar as you have shown above.
我在 MKAnnotationView 中添加了自定义 UIButton。单击该按钮后,我显示了带有 rootViewController 的 popOver,其视图与您上面显示的类似。
回答by bio
I know this question is from 2011 but for people who still find it in a search:
In iOS 9 you have MKAnnotationView.detailCalloutAccessoryView
which entirely replaces the standard callout.
我知道这个问题是从 2011 年开始的,但对于仍然在搜索中找到它的人来说:在 iOS 9 中,MKAnnotationView.detailCalloutAccessoryView
它完全取代了标准标注。