UI进阶——地图的使用

UI进阶——地图的使用

一、简介

地图是IOS开发中常用的模块,很多软件都有试用其定位的程序。
在应用中,想要运用地图功能和定位功能,必须在以下两个框架中进行:
Map Kit:用于地图展示。
Core Location:用于地理定位。
Core Location框架在iOS5之后不用导入。
Core Location中使用的数据类型的前缀都是CL。
Core Location中使用CLLocationManager对象来做用户定位。

二、定位服务

首先新建一个工程,在viewcontroller的.m文件中,声明两个属性:

@property (nonatomic, retain)CLLocationManager* locationManager;//所有的定位服务都需要借助此来完成
@property(nonatomic, retain)CLGeocoder* geocoder;//负责地理编码和反地理编码的核心类

在viewdidload里面写(或者写在其他的方法里,在viewdidload里调用):

  //初始化编码对象
    self.geocoder = [[CLGeocoder alloc] init];


    self.locationManager = [[CLLocationManager alloc] init];
    BOOL isLocation = [CLLocationManager locationServicesEnabled];//判断是否允许定位
    if (!isLocation) {
        //用户未开启定位服务,需要提醒用户开启服务
        NSLog(@"请开启定位");

    }else{
        //取得用户授权
        [self.locationManager requestAlwaysAuthorization];//无论是否在前台,都启用用户授权
        //定位的频率(每隔多少米定位一次)
        self.locationManager.distanceFilter = 10;
        //定位的精确度
        self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
        //设置代理
        self.locationManager.delegate = self;
        //开启定位
        [self.locationManager startUpdatingLocation];
    }

这样子,就可以让应用程序获得定位的权限了。
几个常见的代理方法:

-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{

    NSLog(@"定位失败");
}

//实时获得定位信息
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    //locations数组里存储了一组位置信息
    if (locations.count) {
        CLLocation* location = [locations lastObject];//最新的位置信息,经纬度,速速
        NSLog(@"%@-----",location);
        //发地理编码,将location对象转化为具体的地理编码
        [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
            if (placemarks.count) {
                CLPlacemark* lastPlacemark = [placemarks lastObject];
                NSLog(@"name-----%@",placemarks.lastObject);
                NSLog(@"name-%@",lastPlacemark.name);
                NSLog(@"subLocality----%@",lastPlacemark.subLocality);
                NSLog(@"subAdministrativeArea---%@",lastPlacemark.administrativeArea);
            }
        }];
//        NSLog(@"经度----%.2f----纬度-----%.2f",location.coordinate.longitude,location.coordinate.latitude);
    }else{
        NSLog(@"无定位信息");
    }

}

在这里实时获得位置信息的代理方法,每当用户位置发生改变的时候,都会调用。
对于地理位置的编码和反编码:
因为一般定位获得的是经纬度信息,所以,需要一定的操作来转化为具体的地址。
demo如下:

//地理编码
-(void)geocoderWithPlaceString:(NSString*)placeString{

    [self.geocoder geocodeAddressString:placeString completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        //取出最新的位置信息
        CLPlacemark *pMark = placemarks.lastObject;
        self.lon.text = [NSString stringWithFormat:@"%.2f",pMark.location.coordinate.longitude];
        self.lat.text = [NSString stringWithFormat:@"%.2f",pMark.location.coordinate.latitude];
        NSLog(@"经度--%.2f,纬度--%.2f",pMark.location.coordinate.longitude,pMark.location.coordinate.latitude);
    }];
}
//反地理编码
-(void)geocderWithLocation:(CLLocation*)location{

    [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count) {
            CLPlacemark* lastPlacemark = [placemarks lastObject];
            self.addressView.text = lastPlacemark.name;
            NSLog(@"name:%@",lastPlacemark.name);
            NSLog(@"subLocality:%@",lastPlacemark.subLocality);
            NSLog(@"subAdministrativeArea:%@",lastPlacemark.administrativeArea);
        }

    }];
}

运行效果运行结果
在经纬度转化为地址的时候,会出现卡顿,有时会出现输入的经纬度没有地址。(有可能是荒漠、大海之类的地方);

三、地图显示

声明一个全局变量(属性):

<objectiveC>

@property(nonatomic, retain)MKMapView* mapView;//显示地图控件

懒加载:

-(MKMapView *)mapView{

    if (!_mapView) {
        _mapView = [[MKMapView alloc]initWithFrame:self.view.bounds];

    }
    return _mapView;
}

viewdidload方法:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //设置地图的定位模式
    self.mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;
//    self.mapView.mapType = MKMapTypeSatellite;
    self.mapView.delegate = self;
    [self.view addSubview:self.mapView];
    //系统提供的大头针
    MKPointAnnotation* ann = [[MKPointAnnotation alloc]init];
    ann.title = @"西安";
    ann.subtitle = @"大牛夜市";
    //大头针显示的位置
    ann.coordinate = CLLocationCoordinate2DMake(35.37, 103.86);
    //为地图添加大头针
    [self.mapView addAnnotation:ann];
    MyAnnotation* annn = [[MyAnnotation alloc]init];
    annn.title = @"SB";
    annn.subtitle = @"sssss";
    annn.coordinate = CLLocationCoordinate2DMake(35.38, 103.86);
    [self.mapView addAnnotation:annn];
    //给地图添加了一个手势,可以点击添加大头针
    [self.mapView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapMapView:)]];
}

手势方法及代理方法:

-(void)tapMapView:(UITapGestureRecognizer*)tap{
    //获取点
    CGPoint point=[tap locationInView:self.mapView];
    //点转坐标
    CLLocationCoordinate2D coordi=[self.mapView convertPoint:point toCoordinateFromView:self.mapView];


    NSMutableArray* array = [NSMutableArray arrayWithArray:self.mapView.annotations];


//        [array removeLastObject];
        NSLog(@"%@",self.mapView.annotations);
        [self.mapView removeAnnotations:array];
         NSLog(@"%@",self.mapView.annotations);
    MyAnnotation *anno=[[MyAnnotation alloc]init];
    NSLog(@"纬度--%.2f经度--%.2f",coordi.latitude,coordi.longitude);
    anno.coordinate=coordi;
    anno.title=@"全聚德";
    anno.subtitle=@"来一只鸭子,老板!";
    [self.mapView addAnnotation:anno];

}
#pragma mark <MKMapViewDelegate>

//位置改变,执行代理方法
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{

    NSLog(@"纬度--%.2f经度--%.2f",userLocation.coordinate.latitude,userLocation.coordinate.longitude);
    CLGeocoder* geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        CLPlacemark* placeMark = [placemarks lastObject];
        //设置大头针的标题和副标题
        userLocation.title = placeMark.country;
        userLocation.subtitle = placeMark.name;
    }];
}
//当地图显示区域即将改变的时候,调用的代理
-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated{

    NSLog(@"地图显示区域发生改变");
}

-(void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error{

    NSLog(@"地图加载失败");
}
//自定义大头针

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
    //从重用队列中取出大头针,如果有,直接用。不存在创建
    MKPinAnnotationView* annView =  (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"ANN"];

    if (!annView) {
        annView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:@"ANN"];
    }
    if ([annotation isKindOfClass:[MyAnnotation class]]) {
//        annView.image = [UIImage imageNamed:@"picture_head3.png"];
//        [annView.layer setMasksToBounds:YES];
//        [annView.layer setCornerRadius:25];
        annView.canShowCallout = YES;
        annView.leftCalloutAccessoryView = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
        [annView setAnimatesDrop:YES];
        return annView;
    }
    return nil;

}

地图加载的简单介绍到此为止,深入的使用可以进一步研究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值