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

原文地址:https://www.cnblogs.com/xyzaijing/p/3874342.html