Map地图的用法,可以点击当前位置的一切信息
闲话不说,附上代码
@interface StopManageViewController ()<CLLocationManagerDelegate,MKMapViewDelegate>
{
CustomPinAnnotationView *anotationView;
}
@property (nonatomic, strong) MKMapView*mapView; //!< 地图
@property (nonatomic, strong) CLLocationManager *locManager; //!< 定位
@property (nonatomic, strong) NSMutableArray *annotations;
@end
@implementationStopManageViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.annotations = [NSMutableArray array];
[selfmapView];// 显示地图
[self startLocation]; //启动跟踪定位
self.title=@"停车管理";
}
// 重写get方法(懒加载)
- (MKMapView*)mapView{
if(!_mapView) {
_mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
_mapView.delegate=self;// 设置代理
// 以下所有属性均为YES
_mapView.zoomEnabled =YES;// 允许地图缩放
_mapView.scrollEnabled=YES;// 允许滚动地图
_mapView.rotateEnabled=YES;// 允许两个手指捏合循转
[self.viewaddSubview:_mapView];
}
return _mapView;
}
- (CLLocationManager*)locManager{
if (!_locManager) {
_locManager = [[CLLocationManager alloc] init];
_locManager.delegate=self;//设置代理
//设置定位精度
_locManager.desiredAccuracy=kCLLocationAccuracyBest;
}
return _locManager;
}
// 开始定位
- (void)startLocation
{
[self.locManager startUpdatingLocation];
}
// 停止定位
- (void)stopLocation
{
[self.locManager stopUpdatingLocation];
}
#pragma mark - MKMapViewDelegate
- (nullableMKAnnotationView*)mapView:(MKMapView*)mapView viewForAnnotation:(id)annotation
{
if([annotationisKindOfClass:[KCAnnotationclass]])
{
// 跟tableViewCell的创建一样的原理
staticNSString*identifier =@"kkk";
MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(annotationView ==nil) {
annotationView = [[MKAnnotationViewalloc]initWithAnnotation:annotationreuseIdentifier:identifier];
}
KCAnnotation*ann = annotation;
annotationView.canShowCallout=YES;// 显示大头针小标题
UIImageView * view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
view.image = [UIImage imageNamed:@"white"];
view.layer.cornerRadius=4;
view.layer.masksToBounds=YES;
UILabel * lab = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, view.width-30, 20)];
lab.textAlignment = NSTextAlignmentLeft;
lab.textColor = [UIColor blackColor];
lab.text = ann.address;
[viewaddSubview:lab];
UILabel* titleLab = [[UILabelalloc]initWithFrame:CGRectMake(10, lab.bottom+5,50,20)];
titleLab.textAlignment = NSTextAlignmentLeft;
titleLab.textColor = [UIColorblackColor];
titleLab.adjustsFontSizeToFitWidth = YES;
titleLab.font = [UIFontsystemFontOfSize:13];
titleLab.text =@"剩余车位:";
[viewaddSubview:titleLab];
UILabel* carLab = [[UILabelalloc]initWithFrame:CGRectMake(titleLab.right, lab.bottom+5,20,20)];
carLab.textAlignment = NSTextAlignmentLeft;
carLab.textColor = [UIColorblueColor];
carLab.adjustsFontSizeToFitWidth = YES;
carLab.font = [UIFontsystemFontOfSize:13];
carLab.text = ann.number;
[viewaddSubview:carLab];
UILabel* numLab = [[UILabelalloc]initWithFrame:CGRectMake(carLab.right, lab.bottom+5,70,20)];
numLab.textAlignment = NSTextAlignmentLeft;
numLab.textColor = [UIColorblackColor];
numLab.font = [UIFontsystemFontOfSize:13];
numLab.adjustsFontSizeToFitWidth = YES;
numLab.text =@"总车位:60";
[viewaddSubview:numLab];
UIImageView * imagelab = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
imagelab.image= [UIImageimageNamed:@"gw"];
annotationView.rightCalloutAccessoryView= imagelab;
annotationView.detailCalloutAccessoryView= view;
annotationView.image= [UIImageimageNamed:@"p"];
returnannotationView;
}
return nil; // 设为nil 自动创建系统大头针(唯一区别就是图片的设置)
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{ // 定位管理设置代理 立刻会走该方法,如果你在后台修改了定位模式(如,改为了"永不","使用期间","始终")回到前台都会调用
switch(status) {
case kCLAuthorizationStatusNotDetermined:
{
// 系统优先使用的是 requestWhenInUseAuthorization
if([managerrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[managerrequestWhenInUseAuthorization];
}
if([managerrespondsToSelector:@selector(requestAlwaysAuthorization)]) {
[managerrequestAlwaysAuthorization];
}
}
break;
case kCLAuthorizationStatusDenied:
{
NSLog(@"请开启定位功能!");
}
break;
case kCLAuthorizationStatusRestricted:
{
NSLog(@"定位无法使用!");
}
break;
case kCLAuthorizationStatusAuthorizedAlways:
{
NSLog(@"一直使用定位!");
}
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
{
NSLog(@"使用期间使用定位!");
}
break;
default:
break;
}
}
// 开启了 startUpdatingLocation 就会走这个方法
- (void)locationManager:(CLLocationManager*)manager
didUpdateLocations:(NSArray *)locations
{
NSLog(@"%s",__func__);
/* 设置的定位是best 所以整个方法都会多次调用,调用方法最后一次为理论的最精确,每一次取数组最后的值也为理论的最精确值 */
CLLocation*loc = locations.lastObject;
/* 大概意思是 定位到的时间和回调方法在这一刻有一个时间差 这个差值可以自己定义用来过滤掉一些认为延时太长的数据 */
NSTimeInterval time = [loc.timestamp timeIntervalSinceNow];
// 过滤一些不太满意的数据
if(fabs(time) > 10) return; // 过滤掉10秒之外的(我们只对10秒之内的定位感兴趣)
// 水平精度小于0是无效的定位 必须要大于0 (正数越小越精确)
if (loc.horizontalAccuracy < 0) return;
// verticalAccuracy 这个参数代表的是海拔 暂时不做处理
// 停止定位,否则会一直定位下去(系统会根据偏移的距离来适当的回调,并不是该回调方法一直走,也有可能会走,需要不断地去测试)
[self stopLocation]; // 已经定位到了我们要的位置
//判断是不是属于国内范围
if (![JZLocationConverter isLocationOutOfChina:[loc coordinate]])
{
// 查找地图上是否有大头针
for (id <MKAnnotation> obj in _mapView.annotations)
{
// 有这个类型的大头针先删除掉
if([objisKindOfClass:[KCAnnotationclass]])
{
// 移除添加的大头针 否则会出现满屏的大头针(有增有删)
[_mapViewremoveAnnotation:obj];
}
}
// 转国内火星坐标(不转的的话,偏移特别大,其实我也一直想用系统自带的)
CLLocationCoordinate2D coor = [JZLocationConverter wgs84ToGcj02:loc.coordinate];
CLLocation *location = [[CLLocation alloc] initWithLatitude:coor.latitude longitude:coor.longitude];
CLGeocoder *coder = [[CLGeocoder alloc] init];
// 经纬度转位置信息(该方法必须要联网才能获取)
[coderreverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
for(CLPlacemark*placeinplacemarks) {
NSLog(@"place=%@",place);
NSLog(@"位置=%@ 街道=%@ 子街道=%@ 市=%@ 区县=%@ 行政区域(省)=%@ 国家=%@",place.name,place.thoroughfare,place.subThoroughfare,place.locality,place.subLocality,place.administrativeArea,place.country);
}
}];
NSLog(@"火星坐标 = %f %f",coor.latitude,coor.longitude);
// [self addAnnotation:coor];// 添加大头针
[self addAnnotation];
MKCoordinateSpanspan = {0.01,0.01};// 比例尺 值越小越直观
// 该参数为两个结构体 一个为经纬度,一个为显示比例尺
MKCoordinateRegionregion = {coor,span};
[self.mapViewsetRegion:regionanimated:YES];// 在地图上显示当前比例尺的位置
}else{
// 同上一样的代码
// 查找地图上是否有大头针
for (id <MKAnnotation> obj in _mapView.annotations)
{
// 有这个类型的大头针先删除掉
if([objisKindOfClass:[KCAnnotationclass]])
{
// 移除添加的大头针 否则会出现满屏的大头针(有增有删)
[_mapViewremoveAnnotation:obj];
}
}
// 转国内火星坐标(不转的的话,偏移特别大,其实我也一直想用系统自带的)
CLLocationCoordinate2D coor = [JZLocationConverter wgs84ToGcj02:loc.coordinate];
CLLocation *location = [[CLLocation alloc] initWithLatitude:coor.latitude longitude:coor.longitude];
CLGeocoder *coder = [[CLGeocoder alloc] init];
// 经纬度转位置信息(该方法必须要联网才能获取)
[coderreverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
for(CLPlacemark*placeinplacemarks) {
NSLog(@"place=%@",place);
NSLog(@"位置=%@ 街道=%@ 子街道=%@ 市=%@ 区县=%@ 行政区域(省)=%@ 国家=%@",place.name,place.thoroughfare,place.subThoroughfare,place.locality,place.subLocality,place.administrativeArea,place.country);
}
}];
NSLog(@"火星坐标 = %f %f",coor.latitude,coor.longitude);
// [self addAnnotation:coor]; // 添加大头针
[self addAnnotation];
MKCoordinateSpanspan = {0.01,0.01};// 比例尺 值越小越直观
// 该参数为两个结构体 一个为经纬度,一个为显示比例尺
MKCoordinateRegionregion = {coor,span};
[self.mapViewsetRegion:regionanimated:YES];// 在地图上显示当前比例尺的位置
}
[self addAnnotation];
}
// 添加大头针
- (void)addAnnotation
{
// 要添加大头针,只能遵循创建一个类出来,系统没有提供
CLLocationCoordinate2Dcoordinates[10] = {
{33.569122, 114.032335},
{33.579123, 114.032335},
{33.567124, 114.032335},
{33.568125, 114.032335},
{33.564126, 114.032335},
{33.561127, 114.032335},
{33.565121, 114.032335},
{33.560128, 114.032335},
{33.563129, 114.032335},
{33.559120, 114.032335}};
for(inti =0; i <10; ++i)
{
KCAnnotation*annotation = [[KCAnnotationalloc]init];//KCAnnotation继承于MKAnnotation ,可以在h文件中定义属性,在这里面把所传的数据赋值一下。
annotation.title =@"";
annotation.subtitle =@"";
annotation.coordinate= coordinates[i];
annotation.address = [NSStringstringWithFormat:@"anno: %d", i];
annotation.number = [NSStringstringWithFormat:@"%d",i];
[self.annotationsaddObject:annotation];
}
// 添加大头针,会调用代理方法 mapView:viewForAnnotation:
[_mapView addAnnotations:self.annotations];
// addAnnotations: 该方法可以添加一组大头针
}
效果如下: