一、Xcode中自带地图的使用步骤
1.导入两个框架:CoreLocation.framework、CoreGraphics.framework
2.导入框架
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
3.创建一个MKMapView视图对象。
4.IOS8.0以后要在info.plist中添加字段。
在iOS8 中, 若使用系统自带的地图, 首先在Plist文件中添加两个字段 : NSLocationAlwaysUsageDescription 和 NSLocationWhenInUseUsageDescription 类型均为String类型 其次要注意 : Supported interface orientations 是否存在 不存在则创建 (Array类型);
5.要在代码中判断当前系统的版本,判断当前的iOS版本是否大于8.0。
6.在定位时,要用CLLocationManager类的对象,并且该对象要声明成一个属性。
7.在模拟器的菜单栏中的Debug->Location->Custom中设置此时的经纬度
主要代码
#import "ViewController.h"
#import "LoginViewController.h"
@interface ViewController ()<MKMapViewDelegate,CLLocationManagerDelegate>
//声明一个位置管理对象
@property(nonatomic,strong) CLLocationManager *manager;
@property(nonatomic,strong) CLLocation *userLocation;
@property(nonatomic,strong) MKMapView *map ;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//创建一个地图
_map = [[MKMapView alloc] initWithFrame:[UIScreen mainScreen].bounds];
//添加地图到视图上
[self.view addSubview:_map];
//设置地图的一些属性
//指定一个用户的经纬度
// map.userLocation = @"经纬度";
//是否展示用户的地址
_map.showsUserLocation = YES;
//设置地图模式(默认的是标准的)
_map.mapType = MKMapTypeStandard;
//判断一下当前系统
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
//允许定位 需要在Info.plist里面添加字段,并且和此处保持一致
_manager = [[CLLocationManager alloc] init];
//设置权限为使用时进行定位(要和plist文件中的字段对应)
[_manager requestWhenInUseAuthorization];
//设置跟踪模式 为一直跟踪
[_map setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
//设置地图对象的代理
_map.delegate = self;
//设置位置管理对象的代理
_manager.delegate = self;
//距离筛选器,设置最小的位置更新提示距离
_manager.desiredAccuracy = 1000;
//手动开启定位
[_manager startUpdatingLocation];
}
#pragma mark-----------执行协议方法 MKMapViewDelegate
//用户位置发生了变化
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(@"%d,%s",__LINE__,__FUNCTION__);
NSLog(@"用户的位置发生了改变");
// NSLog(@"title=%@",userLocation.title);
// NSLog(@"subTitle=%@",userLocation.subtitle);
userLocation.title = @"北京";
userLocation.subtitle = @"清河";
#pragma mark-----------系统自带的大头针
//插入一根大头针
//创建一个大头针对象
MKPointAnnotation *point = [[MKPointAnnotation alloc]init];
//通过经纬度创建位置
CLLocationCoordinate2D theLocation = userLocation.coordinate;
//插入的位置
point.coordinate = theLocation;
//将大头针插入地图
[_map addAnnotation:point];
#pragma mark-----------自定义的大头针
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(39.78584, 116);
//创建自定义大头针对象
MyAnnotation *annotation = [[MyAnnotation alloc] initWithTitle:@"金五星商厦" subTitle:@"五层研发11" coordinate:position];
//在地图上添加大头针
[_map addAnnotation:annotation];
//创建一个编码对象
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
//地理编码(根据地址获取经纬度)
[geocoder geocodeAddressString:@"北京" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
NSLog(@"fff%f",placemarks[0].location.coordinate.latitude);
}];
}
#pragma mark---------往地图上添加标记 例如大头针的时候就会走
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
#pragma mark-----------判断大头针的类别
//如果是系统的大头针,则不添加左右视图
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
//创建重用标识符
static NSString *reuseIdentify = @"reuseID";
//根据重用标志符查找是否有创建好的可重用的大头针
MKPinAnnotationView *pinAnnotation =(MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentify];
//判断重用池中是否有该对象
if (!pinAnnotation) {
//没有则创建
pinAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentify];
}
//创建一个图片视图
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 70, 50)];
imgView.image = [UIImage imageNamed:@"1.jpg"];
//创建一个按钮
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 0, 50, 30)];
button.backgroundColor = [UIColor cyanColor];
[button setTitle:@"按钮" forState:UIControlStateNormal];
//添加左视图
[pinAnnotation setLeftCalloutAccessoryView:imgView];
//添加右视图
[pinAnnotation setRightCalloutAccessoryView:button];
//可以显示视图
pinAnnotation.canShowCallout = YES;
return pinAnnotation;
}
#pragma mark---------点击大头针汽泡时候走该方法
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
NSLog(@"点击汽泡时候走");
}
#pragma mark----------点击可编辑区域时候走
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//获取登陆控制器
LoginViewController *loginVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"LoginVC"];
// [self showDetailViewController:loginVC sender:nil];
[self.navigationController pushViewController:loginVC animated:YES];
}
#pragma mark-----------执行协议方法 CLLocationManagerDelegate
//旧位置到新位置
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(@"%d,%s",__LINE__,__FUNCTION__);
NSLog(@"从一个旧的位置到一个新的位置");
}
//位置发生了改变(该方法一直在执行)
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray<CLLocation *> *)locations
{
//里面有经纬度和时间,加速度
NSLog(@"%@",locations.firstObject);
//1.获取经纬度
CLLocation *loc1 = locations.lastObject;
//获取纬度
CLLocationDegrees lati = loc1.coordinate.latitude;
//获取经度
CLLocationDegrees langti = loc1.coordinate.longitude;
//根据获得的此时用户的位置创建一个用户位置对象
_userLocation = [[CLLocation alloc] initWithLatitude:lati longitude:langti];
// NSLog(@"%@",_userLocation);
//创建一个编码对象
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
//地理逆编码,根据经纬度获取具体位置
[geocoder reverseGeocodeLocation:_userLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if(!error)
{
//获得信息
CLPlacemark *placeMark = placemarks[0];
NSLog(@"placeManrk=%@",placeMark);
//获得地址详细信息的字典
NSDictionary *dict = placeMark.addressDictionary;
NSLog(@"dict=%@",dict);
//根据字典获取城市名
NSString *name = dict[@"City"];
NSLog(@"name = %@",name);
//获取街道名
//NSString *street = dict[@""]
// //获得地址信息
// NSLog(@"%@",placeMark.name);
// //获得街道详细信息
// NSLog(@"%@",placeMark.thoroughfare);
// //获得子街道的信息
// NSLog(@"%@",placeMark.subThoroughfare);
// //获得城市名
// NSLog(@"%@",placeMark.locality);
// //获取所在区
// NSLog(@"%@",placeMark.subLocality);
// //行政管理地区
// NSLog(@"%@",placeMark.administrativeArea);
// //其他信息
// NSLog(@"subAdministrativeArea=%@,postalCode=%@,ISOcountryCode=%@,country=%@,inlandWater=%@,ocean=%@,areasOfInterest=%@",placeMark.subAdministrativeArea,placeMark.postalCode,placeMark.ISOcountryCode,placeMark.country,placeMark.inlandWater,placeMark.ocean,placeMark.areasOfInterest);
}
}];
}
@end
//自定义大头针
步骤:
1.创建一个继承自NSObject的类,并遵循<MKAnnotation>协议
2.声明属性
#pragma mark-------声明三个协议中的属性(必须要有)
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, readonly, copy) NSString *title;
@property (nonatomic, readonly, copy) NSString *subtitle;
//自己扩充的属性
@property(nonatomic,assign) NSInteger tag;
3.自定义方法
//自定义一个初始化方法
-(instancetype)initWithTitle:(NSString *)title subTitle:(NSString *)subTitle coordinate:(CLLocationCoordinate2D)coordinate;
(1)如果是iOS8模拟器,会出现如下报错:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
if ([[UIDevice currentDevice].systemVersion doubleValue]>=8.0) { [self.locMgr requestWhenInUseAuthorization]; }