【问题标题】:Customize the MKAnnotationView callout自定义 MKAnnotationView 标注
【发布时间】:2011-12-22 13:28:17
【问题描述】:

我想创建一个自定义 MKAnnotationView 标注,如图所示。我已经测试了几种解决方案,但它们只允许自定义左/右图像和标题/副标题。任何人都可以给我一些源代码或教程链接吗?

目前我一无所知。请帮忙。

【问题讨论】:

  • 我认为这只是一个带有自定义 pin 的自定义视图,你真正的问题是什么?
  • 非常好的问题.. 它也对我有帮助.. 非常感谢 Jennis..

标签: iphone ios ipad mkmapview mkannotationview


【解决方案1】:

我了解到您想要一个带有自定义标注的图钉。

我们无法创建自定义标注,但我们可以创建具有完全自定义视图的注释。所以诀窍是在选择第一个注释时添加第二个注释,并使第二个注释视图看起来像一个标注气泡。

这是用户 djibouti33jacob-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 的项目。

【讨论】:

  • 您好,感谢您所做的出色工作。我正在尝试创建一个注释,为什么其中有两个按钮。当我单击按钮时,会调用 CalloutView 子类的方法 handleTouch。但是发件人是一个UITapGestureRecognizer,在视图属性中带有注释,我希望我的按钮进入sender.view?这是一个众所周知的问题。还是我做错了什么?
  • @amitgupta 提出具体问题。永远不要在没有详细描述您的问题的情况下询问是否有人可以帮助您。见mattgemmell.com/what-have-you-tried
【解决方案2】:

我在 MKAnnotationView 中添加了自定义 UIButton。单击该按钮后,我显示了带有 rootViewController 的 popOver,其视图类似于您在上面显示的视图。

【讨论】:

    【解决方案3】:

    我知道这个问题来自 2011 年,但对于仍然在搜索中找到它的人来说: 在 iOS 9 中,MKAnnotationView.detailCalloutAccessoryView 完全取代了标准标注。

    【讨论】:

      猜你喜欢
      • 2010-11-23
      • 2015-07-19
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      相关资源
      最近更新 更多