首页 > 代码库 > 【iOS开发-110】MapKit框架的主要类MKMapView以及代理方法,大头针的使用addAnnotation

【iOS开发-110】MapKit框架的主要类MKMapView以及代理方法,大头针的使用addAnnotation

#import "ViewController.h"
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>

@interface ViewController ()<MKMapViewDelegate>
@property(nonatomic,strong) CLLocationManager *locMgr;
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@end

@implementation ViewController

-(CLLocationManager *)locMgr{
    if (_locMgr==nil) {
        _locMgr=[[CLLocationManager alloc]init];
    }
    return _locMgr;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    if ([[UIDevice currentDevice].systemVersion doubleValue]>=8.0) {
        [self.locMgr requestWhenInUseAuthorization];
    }
    
    //显示用户位置(蓝色发光圆圈),还有None和FollowWithHeading两种,当有这个属性的时候,iOS8第一次打开地图,会自动定位并显示这个位置。iOS7模拟器上不会。
    self.mapView.userTrackingMode=MKUserTrackingModeFollow;
    
    //地图模式,默认是standard模式,还有卫星模式satellite和杂交模式Hybrid
    self.mapView.mapType=MKMapTypeStandard;
    
    //设置代理
    self.mapView.delegate=self;
}

//MKUserLocation是地图上大头针模型,有title和subtitle以及location信息。该方法调用频繁
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
    NSLog(@"%f,%f",userLocation.location.coordinate.longitude,userLocation.location.coordinate.latitude);
    //点击大头针,会出现以下信息
    userLocation.title=@"中国";
    userLocation.subtitle=@"四大文明古国之一";
    
    //让地图显示用户的位置(iOS8一打开地图会默认转到用户所在位置的地图),该方法不能设置地图精度
//    [mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
    
    //这个方法可以设置地图精度以及显示用户所在位置的地图
    MKCoordinateSpan span=MKCoordinateSpanMake(0.1, 0.1);
    MKCoordinateRegion region=MKCoordinateRegionMake(userLocation.location.coordinate, span);
    [mapView setRegion:region animated:YES];
}

//可以打印经纬度的跨度,用来测试当前视图下地经纬度跨度是多少,然后用于上面的MKCoordinateSpanMake方法中
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    NSLog(@"%f,%f",mapView.region.span.latitudeDelta,mapView.region.span.longitudeDelta);
}

@end

(1)如果是iOS8模拟器,会出现如下报错:

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.


需要添加如下,还需要增加plist中添加NSLocationWhenInUseUsageDescription为YES:

if ([[UIDevice currentDevice].systemVersion doubleValue]>=8.0) {
        [self.locMgr requestWhenInUseAuthorization];
    }

(2)代理方法

常用的就是用户位置更新,区域改变时调用的代理方法。


(3)问题

——显示用户位置所在的地图时,用户位置有时候不在正中间,而是在偏右的地方。难道是模拟器的BUG?


(4)添加一个返回到当前位置的按钮,添加方法:

- (IBAction)backToUserLocation:(id)sender {
    [self.mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate animated:YES];
}

(5)添加大头针

一般顺序是:创建大头针对象 >>> 设置大头针的坐标,标题和子标题 >>> 最后把大头针add添加到地图中

核心是:系统自带的大头针不能设置坐标(只读),所以我们一般是自己写一个继承NSObject的模型,把coordinate,title,subtile属性写进去,关键是这个模型需要遵循<MKAnnotation>。然后用这个大头针类去创建大头针对象。下面就是自定义的大头针类。

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface WPAnnotation : NSObject<MKAnnotation>
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@end

然后使用:

- (void)viewDidLoad {
    [super viewDidLoad];
    ......
    //监听点击,大头针
    [self.mapView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapMapView:)]];
}

-(void)tapMapView:(UITapGestureRecognizer *)tap{
    //获取点击的点
    CGPoint point=[tap locationInView:tap.view];
    //点转换成坐标
    CLLocationCoordinate2D coordi=[self.mapView convertPoint:point toCoordinateFromView:self.mapView];
    //创建大头针模型,设置大头针的坐标,然后把大头针加进去
    WPAnnotation *anno=[[WPAnnotation alloc]init];
    anno.coordinate=coordi;
    anno.title=@"拙政园";
    anno.subtitle=@"苏州市博物馆附近";
    [self.mapView addAnnotation:anno];
}

【iOS开发-110】MapKit框架的主要类MKMapView以及代理方法,大头针的使用addAnnotation