iOS开发基础53-MapKit 框架

一、简介

移动互联网已经深刻改变了用户的生活方式,移动应用可以解决用户生活中的许多琐事。例如,我们可以通过应用来寻找周边的餐馆、KTV和电影院;导航功能可以根据用户设定的起点和终点,规划出合理的路线并指导用户如何到达目的地。这些应用都离不开定位和地图功能。

在 iOS 开发中,涉及到上述功能时必须基于两个核心框架:

  1. CoreLocation:用于实现地理定位、地理编码、区域监听等功能(注重功能实现)。
  2. MapKit:用于地图展示,例如大头针(Annotations)、路线、覆盖层(Overlays)等(注重界面展示)。

二、MapKit框架的使用概述

1. MapKit框架使用前提

在使用 MapKit 之前,需要进行以下几个步骤:

  1. 导入框架:对于 Xcode 5 之后的版本,可以省略这一步,但需要确保在代码中使用框架中的类。

  2. 导入主头文件

    #import <MapKit/MapKit.h>
    

2. MapKit框架使用须知

  • MapKit框架中所有数据类型的前缀都是 MK
  • MKMapView 是 MapKit 框架中最重要的 UI 控件,用于地图显示。

三、地图的基本使用

1. 地图的类型

通过设置 MKMapViewmapType 属性,可以选择不同的地图类型:

  • MKMapTypeStandard:普通地图。
  • MKMapTypeSatellite:卫星地图。
  • MKMapTypeHybrid:混合模式(普通地图覆盖在卫星地图之上)。
  • MKMapTypeSatelliteFlyover:3D立体卫星地图 (需要 iOS 9.0+)。
  • MKMapTypeHybridFlyover:3D立体混合地图 (需要 iOS 9.0+)。
mapView.mapType = MKMapTypeStandard;

2. 设置地图的其他属性

  • 操作项

    • 是否可缩放:zoomEnabled
    • 是否可滚动:scrollEnabled
    • 是否可旋转:rotateEnabled
  • 显示项

    • 是否显示指南针:showsCompass (需要 iOS 9.0+)
    • 是否显示比例尺:showsScale (需要 iOS 9.0+)
    • 是否显示交通:showsTraffic (需要 iOS 9.0+)
    • 是否显示建筑:showsBuildings
mapView.zoomEnabled = YES;
mapView.showsTraffic = YES;

四、跟踪显示用户的位置

1. 显示用户的位置

通过设置 MKMapViewshowsUserLocation 属性,可以显示用户的当前位置:

mapView.showsUserLocation = YES;

显示效果如下,蓝色发光圆点即用户的当前位置,大头针标识用户的位置。

注意:iOS 8.0 之后,需要用户授权进行定位。

2. 追踪用户的位置

通过设置 MKMapViewuserTrackingMode 属性,可以实现对用户当前位置的跟踪:

  • MKUserTrackingModeNone:不跟踪用户的位置。
  • MKUserTrackingModeFollow:跟踪并在地图上显示用户的当前位置。
  • MKUserTrackingModeFollowWithHeading:跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转。
mapView.userTrackingMode = MKUserTrackingModeFollow;

五、设置地图的显示

1. 设置地图的中心点和显示区域

  • 设置地图的中心点位置

    [mapView setCenterCoordinate:coordinate animated:YES];
    
  • 设置地图的显示区域

    [mapView setRegion:region animated:YES];
    

2. MKCoordinateRegion

MKCoordinateRegion是一个描述地图区域的结构体,包含中心点位置和区域跨度:

MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span);

六、MKMapView的代理

MKMapView 可以设置一个代理对象,监听地图相关行为。

常见的代理方法

  • 用户位置更新

    - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
        // 用户位置更新逻辑
    }
    
  • 显示区域变化

    - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
        // 区域即将变化逻辑
    }
    
    - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
        // 区域已经变化逻辑
    }
    

七、大头针(Annotations)

1. 大头针的介绍及基础操作

地图上的大头针用于标识具体位置,添加的基本方法如下:

  • 添加一个大头针

    [mapView addAnnotation:annotation];
    
  • 移除一个大头针

    [mapView removeAnnotation:annotation];
    

2. 大头针模型(MKAnnotation)

大头针模型 id <MKAnnotation> 包含以下属性:

@protocol MKAnnotation <NSObject>
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@optional
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@end

3. 实例:添加大头针

MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.title = @"广州小蛮腰";
annotation.subtitle = @"哎呦,不错哦!";
annotation.coordinate = CLLocationCoordinate2DMake(23.132, 113.345);
[mapView addAnnotation:annotation];

4. 自定义大头针

通过实现 MKMapViewDelegate- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation 方法可以自定义大头针样式:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    if (![annotation isKindOfClass:[MKPointAnnotation class]]) return nil;
    static NSString *ID = @"Annotation";
    MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];
    if (annotationView == nil) {
        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
        annotationView.canShowCallout = YES;
    }
    annotationView.annotation = annotation;
    annotationView.image = [UIImage imageNamed:@"custom_pin_image"];
    return annotationView;
}

八、MKAnnotationView

1. MKAnnotationView属性

  • 图像

    annotationView.image = [UIImage imageNamed:@"image_name"];
    
  • 标注

    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    

2. MKPinAnnotationView子类

MKPinAnnotationViewMKAnnotationView 的子类,提供以下额外属性:

  • 大头针颜色

    pinView.pinColor = MKPinAnnotationColorRed;
    
  • 从天而降

    pinView.animatesDrop = YES;
    

九、系统导航、数字版街景、地图快照

1. 使用 MKMapItem 进行系统导航

- (void)beginNavWithBeginPlacemark:(CLPlacemark *)beginPlacemark andEndPlacemark:(CLPlacemark *)endPlacemark {
    MKPlacemark *placemark1 = [[MKPlacemark alloc] initWithPlacemark:beginPlacemark];
    MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:placemark1];
    
    MKPlacemark *placemark2 = [[MKPlacemark alloc] initWithPlacemark:endPlacemark];
    MKMapItem *item2 = [[MKMapItem alloc] initWithPlacemark:placemark2];
    
    NSDictionary *options = @{
        MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,
        MKLaunchOptionsMapTypeKey: @(MKMapTypeHybridFlyover),
        MKLaunchOptionsShowsTrafficKey: @(YES)
    };
    
    [MKMapItem openMapsWithItems:@[item1, item2] launchOptions:options];
}

2. 使用 MKMapCamera 设置地图街景

MKMapCamera *camera = [MKMapCamera cameraLookingAtCenterCoordinate:center fromEyeCoordinate:eyeCoordinate eyeAltitude:100];
mapView.camera = camera;

3. 使用 MKMapSnapshotter 进行地图截图

MKMapSnapshotOptions *snapOptions = [[MKMapSnapshotOptions alloc] init];
snapOptions.region = mapView.region;
snapOptions.size = mapView.frame.size;
snapOptions.scale = [UIScreen mainScreen].scale;

MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:snapOptions];
[snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
    if (!error) {
        UIImage *image = snapshot.image;
        // 保存图片或显示
    }
}];

十、获取导航路线信息和绘制路线

1. 获取路线信息

MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark];
request.transportType = MKDirectionsTransportTypeAutomobile;

MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
    if (!error) {
        for (MKRoute *route in response.routes) {
            [mapView addOverlay:route.polyline];
        }
    }
}];

2. 绘制导航路线

实现 MKMapViewDelegate- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay 方法,绘制路线:

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
    if ([overlay isKindOfClass:[MKPolyline class]]) {
        MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
        renderer.strokeColor = [UIColor blueColor];
        renderer.lineWidth = 5.0;
        return renderer;
    }
    return nil;
}
posted @ 2015-09-24 22:00  Mr.陳  阅读(2326)  评论(0编辑  收藏  举报