我了解到您想要一个带有自定义标注的图钉。
我们无法创建自定义标注,但我们可以创建具有完全自定义视图的注释。所以诀窍是在选择第一个注释时添加第二个注释,并使第二个注释视图看起来像一个标注气泡。
这是用户 djibouti33 和 jacob-jennings 在答案中发布的解决方案:MKAnnotationView - Lock custom annotation view to pin on location updates,它又基于来自 Asynchrony Solutions 的 blog post。出于解释的目的,这里是来自一个分叉项目的一些 UML:
这是一个大技巧,但也是我见过的实现自定义注释的最简洁的方法。
从一个 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;
// ...
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
// ...
}
}
返回的视图将是 AnnotationView 类型,它实现 AnnotationViewProtocol 来宣布它要处理选择/取消选择。因此,在您的地图视图控制器中,方法 mapView:didSelectAnnotationView: 和 mapView:didDeselectAnnotationView: 应该以与我们之前看到的类似的方式进行委托。
选择注解时,会添加第二个注解 (CalloutAnnotation),它遵循相同的行为,但这次返回的视图 (CalloutView) 是从 XIB 初始化的,并且包含用于动画的 Core Graphics 代码(在 BaseCalloutView 中)并复制标注。
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;
}
为了能够从标注视图推送另一个视图控制器,我使用了通知。
我在顶部链接的 SO 答案包含实现此代码的两个完整项目(类名可能不同)。我在https://github.com/j4n0/callout 有另一个使用上述 UML 的项目。