iOS 6 开发开发定位服务的App在地图上标注位置

在地图上标注位置

前面,我们介绍了如何使用Core Location框架查找用户的位置,也演示了如何转换GPS坐标为具体的地址信息。然而,最直观的方式是在地图上定位该地址。iOS 内置了MapKit API,我们可以很容易使用内置的地图,并在地图上标注位置。

MapKit 框架提供了接口,可将地图直接嵌入到应用程序的视图界面中,也支持在地图标注。MapKit内置在iOS SDK中,支持显示地图、地图导航、添加位置标注和在现有地图上添加覆盖层等等。在本教程中,我们将通过一个示例应用程序,来演示API的基本用法,以及如何在地图上添加标注。

下面是示例应用程序最终设计完成后的运行效果:

创建项目并设计用户界面

我们使用Xcode中的Single View Application模板创建新项目,项目名称为MyAddressMap,类前缀设置为MyAddress,勾选Use Storyboards和Use Automatic Reference Counting复选框。

项目创建好了之后,在项目导航栏中,打开Storyboard文件设计用户界面。我们将创建的默认视图控制器嵌入到导航控制器中。首先,选择视图控制器;接着,选择Editor > Embed in > Navigation Controlller 菜单项。

如果你乐意,可以设置导航栏的标题。如下所示,我们设置导航栏标题为我的地址。接着,从对象库(Object Library)中拖拉Map View对象到视图中。同时,在Map View对象的Attrubites inspector面板窗口,确认勾选Show User Location 复选框。通过启用这一复选框,地图可以自动显示用户的当前位置。

因为应用程序需要Core Location和MapKit框架,我们在项目中添加这两个框架的引用。在项目导航栏选择MyAddressMap,接着选择Targets栏的MyAddressMap,然后选择Build Phases面板,扩展Link Binary with Libraries栏目。点击+按钮,添加CoreLocation和MapKit框架。

添加的2个框架,默认显示在项目导航栏顶部。一般,我们建议将这两个框架拖放到Frameworks 文件夹中,使项目文件管理根据有序一些。

现在,我们还没有编写任何一行代码。在继续之前,我们运行一下App看看是否工作正常。 在App启动时,它将弹出一个窗口,询问是否可以使用你当前位置。轻拍OK按钮,允许使用你当前位置。我们已经创建了一个基本的地图应用程序。

你还记得怎么在iOS模拟器中测试定位App么?iOS 模拟器可以让我们指定一个位置进行测试,选择调试 > 位置 菜单项,你可以进一步自定义位置或者其他位置。下图中的蓝色点,标示我们在地图上的当前位置。

目前为止,我们所做的工作只是简单拖拉UI对象,并完成了在地图上显示当前位置。

放大显示当前位置

当前显示的地图显示了几乎整个中国的地图,通常情况下,我们不希望以这样的比例显示地图,而是放大显示当前位置。

首先,我们在MyAddressMapViewController.h头文件中创建输出口(Outlet),并建立和Map View的连接。在MyAddressMapViewController.h文件中,定义mapView属性,并遵守MKMapViewDelegate协议。同时还需要引用MapKit/MapKit.h头文件,代码如下所示:

#import <UIKit/UIKit.h> #import <MapKit/MapKit.h> @interface MyAddressViewController : UIViewController <MKMapViewDelegate> @property (strong, nonatomic) IBOutlet MKMapView *mapView; @end

接着打开MyAddressViewController.m文件,添加如下@synthesize 指令(在Xcode 4.5 之后版本,由于添加了Automatic Property Synthesize特性): @implementation MyAddressViewController @synthesize mapView;

最后,我们连接Map View和视图控制器之间的委托连接。按住Control 键,拖拉Map View 视图对象到视图控制器图标上,在弹出菜单中,选择delegate。 前面,我们设置视图控制器类遵守MKMapViewDelegate协议,该协议定义了一组可选的方法,我们可以用来接收地图更新的相关信息。如当我们拿着iPhone手机移动的时候,我们的位置将不断改变。为了获取地址更新信息,我们可以实现该协议的相关方法。在Map View接收到新位置信息时,mapView:didUpdateUserLocation 方法将会调用。

这个只是实现MKMapViewDelegate协议的一个例子。我们也可以使用它来更改标注信息,下面会演示这一点。 返回MyAddressViewController.m文件,更新viewDidLoad方法,设置mapView的委托。 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.mapView.delegate = self; }

同时,添加didUpdateUserLocation方法。 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{ MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 600, 600); [self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES]; } 上面的代码是设置Map View在用户当前位置600*600区域放大地图。现在运行App,通过菜单指定用户当前位置,地图将自动放大到指定比例。

在地图上添加标注

从上图中,我们看到用户当前位置标注为一个蓝色的点,但是我们想更改为一个图针。根据iOS 开发指导,如要在地图上显示一个标注,App应该提供如下2个对象:

  • 一个遵守MKAnnotation协议,并管理标注数据的对象;
  • 一个继承自MKAnnotationView 类的视图,用来在地图上可视化显示标注;

iOS内置的MKPointAnnotation标注对象,已经提供了MKAnnotation协议的具体实现。如果标注显示自定义的静态图像,则需要创建一个MKAnnotationView对象,然后将图像赋值给image属性。本示例程序只是简单在地图上显示一个标题,可以使用这个简单的对象。 打开MyAddressViewController.m文件,我们使用MKPointAnnotation对象关联用户当前位置,更新didUpdateUserLocation 方法的代码。 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{ MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 600, 600); [self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];

MKPointAnnotation *point = [[MKPointAnnotation alloc] init]; point.coordinate = userLocation.coordinate; point.title = @"EntLib.com 团队在这里"; point.subtitle = @"http://www.EntLib.com";

[self.mapView addAnnotation:point]; } 为了在地图上显示一个图针显示当前位置,我们首先创建了一个MKPointAnnotation 对象,并赋值coordinate属性为用户当前位置的坐标。接着,我们设置title和subtitle属性。最后,我们调用addAnnotation: 方法,添加标注(annotation)对象到Map View中。

测试MyAddressMap应用程序

现在我们再次运行App,它会在当前位置放置一个图针。轻拍这个图针,将显示标注信息。我们进一步尝试修改用户的当前位置,使用debug 区域顶部的工具条中的箭头按钮,更改到其他位置。

在位置发生改变时,应用程序立即更新到用户的新位置。

总结

在本教程中,我们介绍了MapKit API基本用法,并演示如何在地图上显示用户的当前位置。同时,还介绍如何在地图上放置图针标注用户的位置。

一起学习GIS及其二次开发,一起进步!
原文地址:https://www.cnblogs.com/tuncaysanli/p/2821842.html