iOS地图开发MapKit
现在O2O应用非常火,因为基于地理的社交和电子商务应用都有非常广阔的前景
二O2O的移动载体就是手机了(平板基本忽略不计),所以会点手机上Map开发还是不错的
首先苹果已经封装了一套地图框架供我们使用,首先要使用苹果提供的地图框架需要导入MapKit框架
导入完成后即可使用
首先在你的视图里拖入一个MapView,
然后运行就行了~这是你就会看到地图(如果用的是真机最好,模拟器有点蛋疼)
但是现实的是一个大大的地图,赶脚没什么用,我们需要的是一个比较精准的地图,这时进入MKMapView.h文件中去看看如何使用这个视图
首先看到的是一个代理~这就说明mapView通知外界消息的方式之一用了代理,点入代理会看到很多方法,具体这些方法有什么用自己去探索吧~
然后看到的是一个mapType,这时一个枚举变量,可以看到地图显示的模式有三种,一种是标准,一种是卫星,还有一种是混合的,分别设置然后运行一下就知道他们的区别了
再往下看是一个region属性,下面是一个setRegion方法,点option看一下帮助貌似是我们想要的,那个可以追踪位置的属性
我们尝试着设置一下,但是貌似我们不知道自己所在位置的经纬度,这时候看看代理里面有个叫update的方法,应该是定位用户以后调用的,此时应该已经有经纬度了
尝试着用一下啊
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation { NSLog(@"%f %f", userLocation.coordinate.latitude, userLocation.coordinate.longitude); // 显示用户周边信息 MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 100, 100); [mapView setRegion:region animated:YES]; }
设置完代理,然后实现这个方法以后,果然会定位到当前所在的位置了,上面的结构体都不难,自己查下头文件就好了,其实一个是经纬度,一个是显示比例
有时候我们还需要显示周边的位置信息,并且有醒目的图标,这时候就要用到MKAnnotation协议了,这个协议不是之前常用的代理协议,这种协议是另一种协议
这种协议需要我们自定义类去遵守,并且包含里面有的属性等
/** 在协议中定义属性的用处 可以保证所有遵守该协议的对象,都具有协议定义的属性 使用带属性的协议,通常可以将协议中定义的属性,直接复制到新类中,取消属性的Readonly描述符即可 协议只有.h,也就是只有定义,没有实现。 */ @interface MyAnnotation : NSObject <MKAnnotation> @property (nonatomic, assign) CLLocationCoordinate2D coordinate; @property (nonatomic, copy) NSString *title; @property (nonatomic, copy) NSString *subtitle; @property (nonatomic, strong) NSString *imageName; @end
上面就是一个自定义类,实现协议
如何在地图上添加自定义的点呢?添加自顶一个点其实就是添加一个经纬度,下面的代码就是在mapVIew上添加两个自定义的点
// 添加大头针 MyAnnotation *annotation1 = [[MyAnnotation alloc] init]; annotation1.coordinate = CLLocationCoordinate2DMake(30, 116); annotation1.title = @"我的地盘"; annotation1.subtitle = @"哈哈哈"; annotation1.imageName = @"head0"; [_mapView addAnnotation:annotation1]; MyAnnotation *annotation2 = [[MyAnnotation alloc] init]; annotation2.coordinate = CLLocationCoordinate2DMake(30, 106); annotation2.title = @"重庆"; annotation2.subtitle = @"哈哈哈"; annotation2.imageName = @"head0"; [_mapView addAnnotation:annotation2];
这样在运行一下就加上去了,有时候我们需要自己定义图标,而不用系统自带的那个红头大头针
这个自定义方法应该会在mapView的代理里面,所以我们去代理里面找找,看有没有返回UIView或其子类的方法,
然后就找到了~
下面的代码就是用返回自顶一个视图,代替系统提供的
#pragma mark 自定义大头针视图 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { // 判断annotation参数是否是MyAnnotation // 如果不是MyAnnotaion说明是系统的大头针,无需做处理 if (![annotation isKindOfClass:[MyAnnotation class]]) { // 使用系统默认的大头针 return nil; } // 可重用标示符 static NSString *ID = @"MyAnno"; // 查询可重用的大头针 MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID]; // 如果没有找到,再去实例化大头针 if (annoView == nil) { annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID]; // 自定义大头针视图,如果要接受用户响应,需要设置此属性 annoView.canShowCallout = YES; } // 设置大头针 annoView.annotation = annotation; // 转换成MyAnnotation // 设置大头针视图的图像 MyAnnotation *anno = annotation; annoView.image = [UIImage imageNamed:anno.imageName]; NSLog(@"自定义大头针"); return annoView; }
之所以要判断类型是因为系统的Annotation协议对象没有image属性,如果不判断会崩溃掉
另外我们还经常用到就是计算两点之间的距离,这种需求苹果也想到了.所以这种方法苹果已经封装好了,下面就是实现代码
// 根据经纬度计算两点间的距离 CLLocation *location1 = [[CLLocation alloc] initWithLatitude:30 longitude:116]; CLLocation *location2 = [[CLLocation alloc] initWithLatitude:30 longitude:106]; CLLocationDistance distance = [location1 distanceFromLocation:location2]; NSLog(@"距离:%f", distance);
怎么样?好用吧,不过一般商业级应用都是使用高德和百度地图的SDK~所以真想学点东西的话,出了要了解苹果这一套框架还要去研究研究百度和高德的SDK