使用地图 需要导入MapKit
同样也需要请求用户授权
CoreLocation 是数据类的 定位信息 地理编码 反地理编码
MapKit 控件 显示在屏幕上的视图
MK开头
地图:MKMapView
大头针视图:MKPinAnnotationView
#import "ViewController.h"
//使用地图 需导入MapKit
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<MKMapViewDelegate>
{
CLLocationManager *manage;
MKMapView *myMapView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"没打开");
return;
}
//
// 不管是定位还是使用地图 都需要用户授权
manage = [[CLLocationManager alloc]init];
[manage requestWhenInUseAuthorization];
myMapView = [[MKMapView alloc]initWithFrame:self.view.frame];
// 挂上代理
myMapView.delegate =self;
// 设置地图的样式
/**
MKMapTypeStandard = 0,(默认普通样式)
MKMapTypeSatellite,卫星样式
MKMapTypeHybrid 鸟瞰
*/
myMapView.mapType =MKMapTypeStandard;
// 设置是否允许用户允许旋转地图
myMapView.rotateEnabled =YES;
// 是否允许方法缩小地图
myMapView.zoomEnabled =YES;
// 是否允许地图滚动
myMapView.scrollEnabled = YES;
// 是否允许有3D效果
myMapView.pitchEnabled =YES;
// 射中是否显示用户的位置
myMapView.showsUserLocation =YES;
// 设置移动地图的样式
/**
MKUserTrackingModeNone = 0, // the user's location is not followed(不跟踪用户轨迹)
MKUserTrackingModeFollow, // the map follows the user's location(跟踪用户轨迹)
MKUserTrackingModeFollowWithHeading, // the map follows the user's location and heading(跟踪用户轨迹 地图移动 并且航线也跟随移动)
*/
// myMapView.userTrackingMode =MKUserTrackingModeFollow;
// 设置是否显示附近的建筑物(必须是 普通样式才有效)
myMapView.showsBuildings =YES;
// 是否显示兴趣点(也是 必须是 普通样式 或则鸟瞰样式 有效)
myMapView.showsPointsOfInterest =YES;
[self.view addSubview:myMapView];
UILongPressGestureRecognizer *addPoint = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(addpointView:)];
[myMapView addGestureRecognizer:addPoint];
}
//长按 手势 的方法
-(void)addpointView:(UILongPressGestureRecognizer *)sender
{
// 解决长按手势触发两次
// 在手势开始的时候 执行
if (sender.state==UIGestureRecognizerStateBegan) {
// 把 视图上面的点(point) 转换成 地图上面的坐标
// - (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view
CGPoint point = [sender locationInView:myMapView];
NSLog(@"%f %f",point.x,point.y);
CLLocationCoordinate2D coodinate = [myMapView convertPoint:point toCoordinateFromView:myMapView];
NSLog(@"%f %f",coodinate.latitude,coodinate.longitude);
/*
坐标转点
- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView *)view;
点转坐标
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view;
区域范围转 CGRect
- (CGRect)convertRegion:(MKCoordinateRegion)region toRectToView:(UIView *)view;
CGRect 转 区域范围
- (MKCoordinateRegion)convertRect:(CGRect)rect toRegionFromView:(UIView *)view;
*/
MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc]init];
pointAnnotation.coordinate =coodinate;
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
CLLocation *location = [[CLLocation alloc]initWithLatitude:coodinate.latitude longitude:coodinate.longitude];
// 地理编码和范地理编码都是异步操作
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks lastObject];
pointAnnotation.title = placemark.locality;
pointAnnotation.subtitle = placemark.name;
[myMapView addAnnotation:pointAnnotation];
}];
}
}
#pragma mark 地图代理方法
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView
{
NSLog(@"开始加载");
}
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
NSLog(@"加载完成");
}
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
{
NSLog(@"加载失败");
}
//----将要 开始定位 用户位置的时候调用
- (void)mapViewWillStartLocatingUser:(MKMapView *)mapView
{
NSLog(@"开始定位 用户位置的时候调用");
}
//已经结束定位的时候调用
- (void)mapViewDidStopLocatingUser:(MKMapView *)mapView
{
NSLog(@"结束定位 用户位置的时候调用");
}
//已经 更新完成 用户位置的时候调用
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(@"已经 更新完成 用户位置的时候调用");
// 设置 地图的区域范围
// 设置 地图的区域范围
/*
// 经纬度 变化的比例范围
typedef struct {
CLLocationDegrees latitudeDelta;
CLLocationDegrees longitudeDelta;
} MKCoordinateSpan;
// 区域范围
// 以center 以中心span为比例
typedef struct {
CLLocationCoordinate2D center;
MKCoordinateSpan span;
} MKCoordinateRegion;
*/
// myMapView
MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);
MKCoordinateRegion regin = MKCoordinateRegionMake(userLocation.location.coordinate,span);
// 如果使用Region的时候 用户移动 出现不断跳动的效果 可以屏蔽动画
[myMapView setRegion:regin animated:YES];
// 把地理位置 转换成名字
// 大头针
// 1.数据 MKPointAnnoTation <MKAnnotation>
// 2、视图 MKPinAnnotationView MKAnnotationView
// 大头针 可以理解为 表视图 的 cell
// 使用大头针(标记数据) 可以使用系统提供的MKPointAnnoTation 也可以自定义MKAnnotation
// 地图添加大头针数据 addAnnotation
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
// setCoordinate 设置大头针的经纬度
[annotation setCoordinate:userLocation.location.coordinate];
// 在地里编码 反地理编码 和解码的时候 比较耗时(并且使用了异步的方法)所以 再添加大头针标题副标题的时候 需等 转换完毕 再赋值
// 把定位到用户的位置 转换成地名
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placeMake = [placemarks lastObject];
NSLog(@"城市名:%@ 街道名:%@",placeMake.locality,placeMake.name);
// 给大头针 添加标题
annotation.title = placeMake.locality;
// 给大头针添加副标题
annotation.subtitle = placeMake.name;
// 把大头针数据 添加到地图
[myMapView addAnnotation:annotation];
}];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// 区分用户位置的大头针和插的大头针
// 用户的大头针的数据是MKUserLocation类型
// 长按 插的大头针的数据是 MKPointAnnotation
// 可以通过大头针的数据类型 区分用户的位置
// class 判断是哪一个类
// isKindOfClass是专门判断数据类型的
if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
NSString *annotationID = @"ID";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationID];
if (!annotationView) {
annotationView = [[ MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:annotationID];
annotationView.pinColor = MKPinAnnotationColorPurple;
annotationView.animatesDrop = YES;
}
// annotation大头针数据
annotationView.annotation = annotation;
// canShowCallout设置是否显示标题和副标题
annotationView.canShowCallout = YES;
// 设置大头针的偏移量calloutOffset
// annotationView.calloutOffset = CGPointMake(-1, 5);
// 设置大头针上面显示详情的左侧视图 只要是视图 就可以放在上面
UIImageView *leftView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
leftView.image= [UIImage imageNamed:@"3.jpg"];
annotationView.leftCalloutAccessoryView = leftView;
// 设置大头针是否可以拖动
// annotationView.draggable = YES;
// dragState得到用户拖动大头针的状态
// MKAnnotationViewDragStateNone = 0, // View is at rest, sitting on the map. 没有任何状态
// MKAnnotationViewDragStateStarting, // View is beginning to drag (e.g. pin lift) 开始拖动
// MKAnnotationViewDragStateDragging, // View is dragging ("lift" animations are complete)正在拖动
// MKAnnotationViewDragStateCanceling, // View was not dragged and should return to its starting position (e.g. pin drop)拖动取消
// MKAnnotationViewDragStateEnding // View was dragged, new coordinate is set and view should return to resting position (e.g. pin drop) 拖动结束
return annotationView;
}
return nil;
}
//定位失败
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
{
NSLog(@"定位失败时候调用");
}
本文介绍了如何在iOS应用中使用MapKit和CoreLocation框架实现地图功能,包括导入相关库、请求用户授权、设置地图样式、定位用户位置以及在地图上添加标注等内容。
1771

被折叠的 条评论
为什么被折叠?



