我想自定义iOS8 MapView Callout气泡,点击MKAnnotationView时可以看到它.默认气泡有点限制(只有标题,副标题和2个附件视图)所以我很难找到替代解决方案.这里有两种可能的方式和我面临的相关问题:
问题1)创建一个CUSTOM CALLOUT BUBBLE
挖掘Apple文档我发现了这个:
当您使用自定义视图而不是标准标注时,您需要做额外的工作以确保您的标注在用户与之交互时显示和隐藏.以下步骤概述了创建包含按钮的自定义标注的过程:
设计表示自定义标注的NSView或UIView子类.子类可能需要实现drawRect:方法来绘制自定义内容.创建一个视图控制器,初始化标注视图并执行与按钮相关的操作.在注释视图中,实现hitTest:以响应注释视图边界之外但在callout视图边界内的命中,如清单6-7所示.在注释视图中,实现setSelected:animated:当用户单击或点击它时,将您的标注视图添加为注释视图的子视图.如果callout视图在用户选择它时已经可见,则setSelected:方法应该从注释视图中删除callout子视图(参见清单6-8).在注释视图的initWithAnnotation:方法中,将canShowCallout属性设置为NO以防止在用户选择注释时地图显示标准标注.清单6-7显示了一个实现hitTest的示例:处理callout视图中可能超出注释视图边界的命中.
Listing 6-7 Responding to hits within a custom callout
- (NSView *)hitTest:(NSPoint)point
{
NSView *hitView = [super hitTest:point];
if (hitView == nil && self.selected) {
NSPoint pointInAnnotationView = [self.superview convertPoint:point toView:self];
NSView *calloutView = self.calloutViewController.view;
hitView = [calloutView hitTest:pointInAnnotationView];
}
return hitView;
}
Run Code Online (Sandbox Code Playgroud)
清单6-8显示了实现setSelected:animated:的示例,用于在用户选择注释视图时为自定义标注视图的到达和解除设置动画.
Listing 6-8 Adding and removing a custom callout view
- (void)setSelected:(BOOL)selected
{
[super setSelected:selected];
// Get the custom callout view.
NSView *calloutView = self.calloutViewController.view;
if …Run Code Online (Sandbox Code Playgroud) 我的地图视图有一个自定义注释。我最初使用一些数据设置了坐标、标题(例如“第一个标题”)、副标题(例如“第一个地址”)、userId 和距离(例如 0 米)属性。我将其添加到 mapView 和数组中以供以后使用。一切正常,它显示在地图视图上,我按下它,标注显示初始数据。
后来我得知该标注的位置已更改。我循环遍历数组并使用坐标、标题(例如“新标题”)、副标题(例如“新地址”)和距离(例如 100 米)属性的新数据更新标注。我还将标注从原始位置动画化到新位置。动画工作正常,标注从 A 点移动到 B 点。
问题是,当我点击注释时,旧数据会显示在标注上,而不是新数据。
我过去常calloutAccessoryControlTapped推新的VC。当我在那里放置断点时,自定义引脚具有所有新数据。该错误似乎是在标注时发生的。
我该如何解决?
我不想清除地图视图中的所有注释,所以这不是一个选项。我致电mapView.removeAnnotation(customPin)并mapView.addAnnotation(customPin)解决了该图钉的问题,但是当图钉被移除并添加回地图时,会出现闪烁,然后当它动画到新位置时,它看起来不稳定。
自定义注释
class CustomPin: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?
var userId: String?
var distance: CLLocationDistance?
init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String, userId: String, distance: CLLocationDistance?) {
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
self.userId = userId
self.distance = distance
super.init()
}
}
Run Code Online (Sandbox Code Playgroud)
第一次使用初始数据设置注释
firstFunctionThatGetsTheInitialLocation(origLat, origLon) {
let …Run Code Online (Sandbox Code Playgroud)