地图框架:#import <MapKit/MapKit.h>
基本属性和方法:
属性:
- 地图类视图:MKMapView
- 地图类型:MKMapType mapType
- 地图旋转:rotateEnabled
- 用户追踪:MKUserTrackingMode userTrackingMode
- 地图区域:MKCoordinateRegion region
- 地图代理方法:MKMapViewDelegate
- 用户位置类:MKUserLocation
- 大头针类:MKAnnotation
- 请求用户授权:requestAlwaysAuthorization
方法:
- 地图的区域改变完成时调用:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
- 每次更新到用户的位置就会调用(调用不频繁, 只有位置改变才会调用):
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
- 每次添加大头针就会调用(地图上有几个大头针就调用几次):
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
MapKit方法的基本实现:
A、添加地图,并且更新到用户位置
1 #import "ViewController.h" 2 #import <MapKit/MapKit.h> 3 4 @interface ViewController ()<MKMapViewDelegate> 5 // 地图 6 @property (nonatomic,strong) MKMapView *mapView; 7 @property (nonatomic, strong) CLLocationManager *mgr; 8 // 地理编码对象 9 @property (nonatomic ,strong) CLGeocoder *geocoder; 10 @end 11 12 @implementation ViewController 13 14 // 懒加载 - mapView 15 - (MKMapView *)mapView 16 { 17 if (!_mapView){ 18 19 _mapView = [[MKMapView alloc] initWithFrame:self.view.bounds]; 20 // 标准地图 21 /* 22 typedef enum : NSUInteger { 23 MKMapTypeStandard , 标准(默认) 24 MKMapTypeSatellite ,卫星 25 MKMapTypeHybrid 混合(标准 + 卫星) 26 } MKMapType; 27 */ 28 _mapView.mapType = MKMapTypeStandard; 29 30 31 // 追踪用户 32 // 如果想利用MapKit获取用户的位置, 可以追踪 33 /* 34 typedef NS_ENUM(NSInteger, MKUserTrackingMode) { 35 MKUserTrackingModeNone = 0, 不追踪/不准确的 36 MKUserTrackingModeFollow, 追踪 37 MKUserTrackingModeFollowWithHeading, 追踪并且获取用的方向 38 } 39 */ 40 _mapView.userTrackingMode = MKUserTrackingModeFollow; 41 42 [self.view addSubview:_mapView]; 43 } 44 45 return _mapView; 46 } 47 48 #pragma mark - 懒加载 49 - (CLGeocoder *)geocoder 50 { 51 if (!_geocoder) { 52 _geocoder = [[CLGeocoder alloc] init]; 53 } 54 return _geocoder; 55 } 56 57 58 - (void)viewDidLoad { 59 [super viewDidLoad]; 60 61 // 注意:在iOS8中, 如果想要追踪用户的位置, 必须自己主动请求隐私权限 62 if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { 63 // 主动请求权限 64 self.mgr = [[CLLocationManager alloc] init]; 65 66 [self.mgr requestAlwaysAuthorization]; 67 } 68 69 70 // 成为mapVIew的代理 71 self.customMapView.delegate = self; 72 73 } 74 75 #pragma MKMapViewDelegate 76 // 每次更新到用户的位置就会调用(调用不频繁, 只有位置改变才会调用) 77 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 78 { 79 80 // 利用反地理编码获取位置之后设置标题 81 [self.geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) { 82 CLPlacemark *placemark = [placemarks firstObject]; 83 NSLog(@"获取地理位置成功 name = %@ locality = %@", placemark.name, placemark.locality); 84 userLocation.title = placemark.name; 85 userLocation.subtitle = placemark.locality; 86 }]; 87 88 89 90 // 移动地图到当前用户所在位置 91 // 获取用户当前所在位置的经纬度, 并且设置为地图的中心点 92 // [self.customMapView setCenterCoordinate:userLocation.location.coordinate animated:YES]; 93 94 // 设置地图显示的区域 95 // 获取用户的位置 96 CLLocationCoordinate2D center = userLocation.location.coordinate; 97 // 指定经纬度的跨度 98 MKCoordinateSpan span = MKCoordinateSpanMake(0.009310,0.007812); 99 // 将用户当前的位置作为显示区域的中心点, 并且指定需要显示的跨度范围 100 MKCoordinateRegion region = MKCoordinateRegionMake(center, span); 101 102 // 设置显示区域 103 [self.customMapView setRegion:region animated:YES]; 104 } 105 106 107 // 地图的区域改变完成时调用 108 - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 109 { 110 // 获取到经纬度跨度 111 NSLog(@"%f %f", self.customMapView.region.span.latitudeDelta, self.customMapView.region.span.longitudeDelta); 112 } 113 114 @end
B、在地图上添加自定义的大头针:
-
- 需要自定义一个遵守MKAnnotation协议的NSObject类
- 需要在自定义的类中定义MKAnnotation里面的属性,同时也可以自行扩展属性
- 在控制器中使用自定义类添加大头针
1、自定义大头针类:
1 #import <Foundation/Foundation.h> 2 #import <MapKit/MapKit.h> 3 4 @interface WYSAnnotation : NSObject<MKAnnotation> 5 // 大头针的位置 6 @property (nonatomic, assign) CLLocationCoordinate2D coordinate; 7 // 大头针标题 8 @property (nonatomic, copy) NSString *title; 9 // 大头针的子标题 10 @property (nonatomic, copy) NSString *subtitle; 11 12 // 图标 - 自己扩展的属性 13 @property (nonatomic, copy) NSString *icon;
2、在ViewController中添加大头针:
1 // 创建大头针模型 2 WYSAnnotation *anno = [[HMAnnotation alloc] init]; 3 anno.title = @"GeekStar"; 4 anno.subtitle = @"贵在坚持"; 5 // 大头针添加在随机经纬度位置 6 CGFloat latitude = 32.22 + arc4random_uniform(5); 7 CGFloat longitude = 132.48 + arc4random_uniform(5); 8 anno.coordinate = CLLocationCoordinate2DMake(latitude , longitude); 9 anno.icon = @"hehe.jpg"; 10 11 // 添加大头针 12 [self.mapView addAnnotation:anno];
3、实现大头针的代理方法:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { // 对用户当前的位置的大头针特殊处理,直接使用系统提供的大头针 if ([annotation isKindOfClass:[HMAnnotation class]] == NO) { return nil; } // 缓存 static NSString *identifier = @"anno"; //缓存池中取 // 注意: 默认情况下MKAnnotationView是无法显示的, 如果想自定义大头针可以使用MKAnnotationView的子类MKPinAnnotationView // 注意: 如果是自定义的大头针, 默认情况点击大头针之后是不会显示标题的, 需要我们自己手动设置显示 // MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; // 2.如果缓存池中没有, 创建一个新的 if (annoView == nil) { // annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier]; annoView = [[MKAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:identifier]; // 设置大头针的颜色 // annoView.pinColor = MKPinAnnotationColorPurple; // 设置大头针从天而降 // annoView.animatesDrop = YES; // 设置大头针标题是否显示 annoView.canShowCallout = YES; // 设置大头针标题显示的偏移位 // annoView.calloutOffset = CGPointMake(-50, 0); // 设置大头针左边的辅助视图 annoView.leftCalloutAccessoryView = [[UISwitch alloc] init]; // 设置大头针右边的辅助视图 annoView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd]; } // 设置大头针的图片 // 注意: 如果你是使用的MKPinAnnotationView创建的自定义大头针, 那么设置图片无效, 因为系统内部会做一些操作, 覆盖掉我们自己的设置 // annoView.image = [UIImage imageNamed:@"hehe.jpg"]; HMAnnotation *anno = (HMAnnotation *)annotation; annoView.image = [UIImage imageNamed:anno.icon]; // 3.给大头针View设置数据 annoView.annotation = annotation; // 4.返回大头针View return annoView; }
C、ios系统自带导航:
1 #import "ViewController.h" 2 #import <MapKit/MapKit.h> 3 4 @interface ViewController () 5 6 // 地理编码对象 7 @property(nonatomic, strong) CLGeocoder *geocoder; 8 @end 9 10 @implementation ViewController 11 12 #pragma mark - 懒加载 13 - (CLGeocoder *)geocoder 14 { 15 if (!_geocoder) { 16 self.geocoder = [[CLGeocoder alloc] init]; 17 } 18 return _geocoder; 19 } 20 21 22 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 23 { 24 // 获取用户输入的起点和终点 25 NSString *startStr = @"上海"; 26 NSString *endStr = @"北京"; 27 28 29 // 地理编码 30 [self.geocoder geocodeAddressString:startStr completionHandler:^(NSArray *placemarks, NSError *error) { 31 if (placemarks.count == 0) return; 32 33 // 开始位置的地标 34 CLPlacemark *startCLPlacemark = [placemarks firstObject]; 35 36 37 // 地理编码 38 [self.geocoder geocodeAddressString:endStr completionHandler:^(NSArray *placemarks, NSError *error) { 39 40 if (placemarks.count == 0) return; 41 42 // 结束位置的地标 43 CLPlacemark *endCLPlacemark = [placemarks firstObject]; 44 45 // 开始导航 46 [self startNavigationWithstartCLPlacemark:startCLPlacemark endCLPlacemark:endCLPlacemark]; 47 }]; 48 49 }]; 50 } 51 52 // 开始导航 53 - (void)startNavigationWithstartCLPlacemark:(CLPlacemark *)startCLPlacemark endCLPlacemark:(CLPlacemark *)endCLPlacemark 54 { 55 56 //创建起点 57 MKPlacemark *startPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark]; 58 MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startPlacemark];; 59 60 //创建终点 61 MKPlacemark *endPlacemark = [[MKPlacemark alloc] initWithPlacemark:endCLPlacemark]; 62 MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endPlacemark]; 63 64 // 设置数组 65 NSArray *items = @[startItem, endItem]; 66 67 68 // 设置属性 69 NSMutableDictionary *options = [NSMutableDictionary dictionary]; 70 // 模式 71 options[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving; 72 73 // 开启系统导航 74 [MKMapItem openMapsWithItems:items launchOptions:options]; 75 } 76 77 78 @end
时间: 2024-11-09 05:05:37