《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.4节地图注释和覆盖层

简介:

本节书摘来自异步社区《iOS组件与框架——iOS SDK高级特性剖析》一书中的第2章,第2.4节地图注释和覆盖层,作者 【美】Kyle Richter , Joe Keeley,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.4 地图注释和覆盖层
iOS组件与框架——iOS SDK高级特性剖析
地图视图(MKMapView)是一种可滚动的视图,行为独特;以标准方式在其中添加子视图时,子视图不会随地图视图滚动,而是静止的,其相对于地图视图框架的位置始终不变。对悬停按钮或标签来说,这种特点也许不错,但在地图上标出点和细节至关重要。要标出地图视图中感兴趣的点或区域,可使用地图注释和覆盖层。地图滚动或缩放时,注释和覆盖层在地图上的位置保持不变。地图注释是使用地图上的单个坐标点定义的,而地图覆盖层可以是线段、多边形或复杂形状。MapKit将注释(覆盖层)同其关联的视图区分开来。注释和覆盖层是数据,指定了相关联的视图应显示在地图的什么地方,这些数据被直接添加到地图视图中。在需要显示注释或覆盖层时,地图视图将请求相关联的视图,就像表视图根据需要为索引路径请求单元格一样。

2.4.1 添加注释
任何对象都可用作地图视图中的注释,前提条件是它实现了协议MKAnnotation。Apple建议注释对象应是轻量级的,因为对于添加的每个注释,地图视图都将包含一个指向它的引用;另外,如果注释太多,可能影响地图的滚动和缩放性能。如果注释非常简单,可使用MKPointAnnotation类。在示例应用中,ICFFavoritePlace实现了协议MKAnnotation,它是NSManagedObject的子类,因此可使用Core Data进行持久化。有关如何使用Core Data和NSManagedObject子类的更详细信息,请参阅第13章。

要实现协议MKAnnotation,类必须实现属性coordinate,地图视图将使用这个属性确定将注释放在地图的什么地方。属性coordinate的获取方法返回一个CLLocationCoordinate2D。


db852ae2bb010124068949107252decc139e98ff

由于ICFFavoritePlace类存储了地点的经度和纬度,因此属性coordinate的获取方法根据经度和纬度创建一个CLLocationCoordinate2D,这是使用Core Location提供的函数CLLocationCoordinate2DMake完成的。在属性coordinate的设置方法中,ICFFavoritePlace存储CLLocationCoordinate2D参数中的经度和纬度。


f71a74dd551aab48acbd5a24b89dcfe362161111

协议MKAnnotation还定义了另外两个可选属性:title和subtitle。在用户轻按注释视图时,地图视图可使用这两个属性来显示标注(callout),如图2.7所示。


0fd88ef5465cd99d550c10a9a1766d9254fe9896

在ICFMainViewController的方法viewDidLoad:中,调用了方法updateMapAnnotations来填充初始地图注释,在地点详情编辑视图被关闭时,也调用了这个方法。这个方法首先将地图视图的注释都删除。虽然注释不多时这种方式完全可行,但注释很多时,必须设计更智能的方式,以高效地删除不需要的注释并添加新的注释。


277aceceb4110da8ee726796b892c3e3a6b9fb88

2.4.2 显示标准和自定义的注释视图
注释视图在地图上表示注释。MapKit提供了两种标准注释视图:大头针(表示搜索到的位置)和蓝点(表示当前位置)。可使用静态图像定制注释视图,还可通过创建MKAnnotationView子类来全面定制注释视图。在示例应用中,在用户喜欢的地方显示标准大头针,在当前位置显示标准蓝点,而可拖曳的注释则使用绿色箭头表示,如图2.8所示。

为让地图视图显示注释视图,地图视图委托需要实现方法mapView:viewForAnnotation。在示例应用中,方法mapView:viewForAnnotation是在ICFMainViewController中实现的,它首先检查注释是否是当前位置。


76b9899b5ef4d989cf4f6a3dace204e645077deb

如果是当前位置,就返回nil,这让地图视图使用标准蓝点。接下来,这个方法检查注释的类型。如果注释表示的位置为下一个目的地(goingNext),就返回一个自定义注释视图,否则返回标准的大头针注释视图。


8264a8946887f813da9ba1654cfb5b3e80f05da1

为返回标准的大头针注释视图,这个方法首先尝试从队列中取出一个未用的注释视图。如果没有这样的注释视图,就创建一个MKPinAnnotationView实例。


6246534420f678bea8d7259593859e812ce4aa54

创建大头针注释视图后,就可对其进行定制了:设置大头针的颜色(可设置为红色、绿色或紫色)、指定用户轻按注释视图时是否显示说明、指定注释视图是否是可拖曳的。


4a1b6e598d13dab141462595fdad98f4a690d0ee

轻按注释视图显示的说明包含可定制的左扩展视图(accessory view)和右扩展视图。左扩展视图被设置为一幅自定义图像,而右扩展视图被设置为标准的展开按钮。如果左扩展视图或右扩展视图是从UIControl派生而来的对象,用户轻按它们时将调用委托方法mapView:annotation View:calloutAccessoryControlTapped:。

否则,开发人员应对这些对象进行配置,使其对轻按做出响应。请注意,Apple规定扩展视图的高度不能超过32像素。


25f77c44fbab9d8af8736344e71b799692ed9a96

这种注释视图将显示为绿色箭头,而不是标准大头针,如图2.8所示。

2.4.3 可拖曳的注释视图
可拖曳的注释视图很有用,它让用户能够在地图上指定地点。在示例应用中,有个特殊的地点,它是用户的下一个目的地,用绿色箭头表示。可让注释视图是可拖曳的,为此可将其属性draggable设置为YES。


a87f4333e419240404ebd24aaf0623d44871f0ee

这样,用户就可将它拖曳到地图的任何地方。为更详细地了解用户是如何拖曳注释视图的,地图视图委托实现了方法mapView:annotationView:didChangeDragState:fromOldState:。每当可拖曳注释视图的拖曳状态发生变化时,都将调用这个方法,并指出拖曳状态为无(MKAnnotationViewDragStateNone)、即将开始、正在拖曳、即将撤销还是即将结束。通过查看新的拖曳状态和旧的拖曳状态,可编写自定义逻辑来处理众多不同的拖曳情形。

在示例应用中,当用户停止拖曳绿色箭头时,将对箭头指定的新位置进行反向地理编码(这将在 2.5 节更详细地介绍),以获取新位置的名称和地址。为此,这个方法需要检查拖曳是否已结束。


c0913aaae3821731c6e1c2e3f9d12f38179545c0

2.4.4 使用地图覆盖层
地图覆盖层类似于地图注释,可以是任何实现了协议MKOverlay的对象,而地图视图委托将负责提供与地图覆盖层相关联的视图。地图覆盖层不同于注释的地方在于,它们不仅可以表示点,还可以表示线段和形状,因此非常适合用于在地图上表示线路或感兴趣的区域。为演示地图覆盖层,示例应用提供了给喜欢的地点添加地理围栏的功能(这将在后面的2.6节更详细地介绍),围栏的半径由用户指定。给喜欢的地点添加地理围栏后,将在地图上显示一个圆,其半径是用户指定的值,圆心为喜欢的地点,如图2.9所示。


b3af9f476ee2f1370f077649b4488bc7b826f433

前面的2.4.1节说过,方法updateMapAnnotations给地图添加注释;这个方法还给地图添加覆盖层。为此,它清除地图视图中的所有覆盖层。


2e9dfeb02ce444420addb4907fb3663bf22bd2da

由于仅当地点启用了地理围栏功能时,才需要为它显示覆盖层,因为这个方法迭代所有的地点,并为启用了地理围栏功能的地点添加覆盖层。


25a55141c5ee906c7714c099bd1eb1174a1da755
相关文章
|
3月前
|
机器学习/深度学习 PyTorch TensorFlow
是否有其他框架可以在iOS设备上进行机器学习?
是否有其他框架可以在iOS设备上进行机器学习?
21 1
|
3月前
|
存储 数据建模 iOS开发
iOS设备功能和框架: 什么是 Core Data,它在 iOS 中的作用是什么?
iOS设备功能和框架: 什么是 Core Data,它在 iOS 中的作用是什么?
32 1
|
3月前
|
定位技术 iOS开发
iOS设备功能和框架: 如何使用 Core Location 获取设备的位置信息?
iOS设备功能和框架: 如何使用 Core Location 获取设备的位置信息?
19 0
|
7月前
|
开发工具 iOS开发
iOS 支付宝SDK比较隐秘的坑
iOS 支付宝SDK比较隐秘的坑
113 0
|
3月前
|
机器学习/深度学习 PyTorch TensorFlow
iOS设备功能和框架: 什么是 Core ML?如何在应用中集成机器学习模型?
iOS设备功能和框架: 什么是 Core ML?如何在应用中集成机器学习模型?
27 0
|
3月前
|
iOS开发
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
101 0
|
4月前
|
测试技术 API 开发工具
|
4月前
|
分布式计算 Hadoop Java
hadoop sdk 优化小结(裁剪、集成kerberos组件、定制等)
hadoop sdk 优化小结(裁剪、集成kerberos组件、定制等)
41 0
|
5月前
|
小程序 开发工具 Android开发
Donut多端框架小程序打包适配ios和安卓app
腾讯新出了一个 Donut 多端框架,可以直接将微信小程序转成 ios 和 安卓 app,小程序开发者工具里也集成了 app 相关升级、调试和打包的功能,终于可以一套代码开发出3个客户端了!
124 0
Donut多端框架小程序打包适配ios和安卓app
|
5月前
|
移动开发 网络协议 安全
基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v8.0版已发布
MobileIMSDK 是一套专门为移动端开发的开源IM即时通讯框架,超轻量级、高度提炼,一套API优雅支持 UDP 、TCP 、WebSocket 三种协议,支持 iOS、Android、H5、标准Java、小程序、Uniapp,服务端基于Netty编写。
69 0