概要
本章主要简示了IOS里面位置服务的使用,包括定位,地图,地图标记以及地图定位。由于现在的地图开发和以前的差别比较大,而且地图涉及的东西相对而言复杂点,所以本实验耗时比较多,有的地方还存在一些问题。
结果展示
注意文本框的两个数字是当前的经纬度,地图视图切换是切换到该经纬度的位置,最后红色的那个标注即为地图中的经纬度,不过由于经纬度解析部分有问题,所以未能显示经纬度的对应地址是什么。(示例里面不是使用代理来解析经纬度的,使用的是CLGeocoder,因为以前使用的代理官方建议不再使用了。)
流程概要
1.在开始工程之前需要知道主要步骤:a.定位当前的地址 b.解析经纬度获取对应的地址,然后地图视图切换到该位置 c.在地图上标注该位置
2.定位部分因为看到的教程较老,所以实际操作有差别,最新的定位需要增加授权。其主要方法是在修改info.list文件,然后再代码里面添加授权代码。如下所示:
/* 1.Info.plist中加入两个缺省没有的字段 NSLocationAlwaysUsageDescription NSLocationWhenInUseUsageDescription 并设置值为YES */ //2.在启动定位前设置授权 // 开始定位 -(void)onLocate { self._textLocationInfo.text = @""; self._locateManage = [[CLLocationManager alloc] init]; self._locateManage.delegate = self; self._locateManage.desiredAccuracy = kCLLocationAccuracyBest; self._locateManage.distanceFilter = 1000; // 新版本需要授权 if ([[[UIDevice currentDevice] systemVersion] doubleValue] > 8.0) { [self._locateManage requestWhenInUseAuthorization]; } [self._locateManage startUpdatingLocation]; [self._locateActivityIndicator startAnimating]; }
3.实现定位代理的协议和地图代理协议,主要是完成以下方法:
#pragma 实现协议CLLocationManagerDelegate // 定位成功调用该方法,数组里面最后的成员为最新的地址 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations // 授权完成调用该方法,可查看授权状态 - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status; // 定位失败调用该方法 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error; #pragma 实现协议MKMapViewDelegate // 画标注 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
4.在获取地址成功后,根据地址中的经纬度设置地图视图,然后使用CLGeocoder解析经纬度地址。
5.解析出地址后需要在地图上标注出当前位置,此时需要新建一个类,实现标注的协议,指定标注的经纬度、标题以及子标题
6.完成后,停止定位
主要代码
h文件
// // ViewController.h // FindMe // // Created by God Lin on 14/12/13. // Copyright (c) 2014年 arbboter. All rights reserved. // #import <UIKit/UIKit.h> #import <MapKit/MapKit.h> #import <CoreLocation/CoreLocation.h> @interface ViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate> { MKMapView* _mapView; UIButton* _buttonLocate; UITextView* _textLocationInfo; UIActivityIndicatorView* _locateActivityIndicator; CLLocationManager* _locateManage; } @property (nonatomic, retain) MKMapView* _mapView; @property (nonatomic, retain) UIButton* _buttonLocate; @property (nonatomic, retain) UITextView* _textLocationInfo; @property (nonatomic, retain) UIActivityIndicatorView* _locateActivityIndicator; @property (nonatomic, retain) CLLocationManager* _locateManage; @end
m文件
// // ViewController.m // FindMe // // Created by God Lin on 14/12/13. // Copyright (c) 2014年 arbboter. All rights reserved. // #import "ViewController.h" #import "MapLocation.h" @interface ViewController () @end @implementation ViewController @synthesize _buttonLocate, _locateActivityIndicator, _mapView, _textLocationInfo; @synthesize _locateManage; // 界面控件布局 -(void)autoLayout { CGFloat _x = self.view.frame.origin.x; CGFloat _y = self.view.frame.origin.y; CGFloat _w = self.view.frame.size.width; CGFloat _h = self.view.frame.size.height; CGFloat xEdge = 10; CGFloat yEdge = 10; CGFloat x = _x + xEdge; CGFloat y = _y + 2*yEdge; CGFloat w = _w - 2*xEdge; CGFloat h = 50; self._mapView.frame = CGRectMake(x, y, w, _h - y - yEdge - h); y = self._mapView.frame.origin.y + self._mapView.frame.size.height + yEdge; h -= 5; self._buttonLocate.frame = CGRectMake(x, y, w/5, h); self._buttonLocate.layer.cornerRadius = 10; self._buttonLocate.layer.borderWidth = 1; [self._buttonLocate setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [self._buttonLocate setTitle:@"Locate" forState:UIControlStateNormal]; CGFloat xSameLevelEdge = 2; x = x + self._buttonLocate.frame.size.width; self._textLocationInfo.frame = CGRectMake(x+xSameLevelEdge, y, 4*w/5-xSameLevelEdge, h); self._textLocationInfo.layer.borderWidth = 1; self._textLocationInfo.layer.cornerRadius = 10; self._textLocationInfo.editable = NO; self._locateActivityIndicator.frame = CGRectMake(0,0, h*2, h*2); [self._locateActivityIndicator setCenter:CGPointMake(_w/2, _h/2)]; [self._locateActivityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge]; self._locateActivityIndicator.color = [UIColor blackColor]; } // 开始定位 -(void)onLocate { self._textLocationInfo.text = @""; self._locateManage = [[CLLocationManager alloc] init]; self._locateManage.delegate = self; self._locateManage.desiredAccuracy = kCLLocationAccuracyBest; self._locateManage.distanceFilter = 1000; // 新版本需要授权 if ([[[UIDevice currentDevice] systemVersion] doubleValue] > 8.0) { [self._locateManage requestWhenInUseAuthorization]; } [self._locateManage startUpdatingLocation]; [self._locateActivityIndicator startAnimating]; } -(void)stopLocate { if(self._locateManage) { [self._locateManage stopUpdatingLocation]; self._locateManage.delegate = nil; [self._locateManage release]; self._locateManage = nil; [self._locateActivityIndicator stopAnimating]; } } - (void)viewDidLoad { [super viewDidLoad]; self._mapView = [[MKMapView alloc] init]; [self.view addSubview:self._mapView]; self._buttonLocate = [[UIButton alloc] init]; [self._buttonLocate addTarget:self action:@selector(onLocate) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:self._buttonLocate]; self._textLocationInfo = [[UITextView alloc] init]; [self.view addSubview:self._textLocationInfo]; self._locateActivityIndicator = [[UIActivityIndicatorView alloc] init]; [self.view addSubview:self._locateActivityIndicator]; [self autoLayout]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)dealloc { [_locateActivityIndicator release]; [_mapView release]; [_textLocationInfo release]; [_buttonLocate release]; [super dealloc]; } #pragma 实现协议CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"%@", locations); CLLocation* curLocation = [locations lastObject]; // 地图定位到当前位置 MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(curLocation.coordinate, 1000, 1000); viewRegion = [self._mapView regionThatFits:viewRegion]; [self._mapView setRegion:viewRegion animated:YES]; // 解析经纬度为地址,在地图上添加标注 MapLocation* annotation = [[MapLocation alloc] init]; annotation.coordinate = curLocation.coordinate; CLGeocoder* geoCoder = [[CLGeocoder alloc] init]; [geoCoder reverseGeocodeLocation:curLocation completionHandler:^(NSArray *placemarks, NSError *error) { if(error) { NSLog(@"CLGeocoder error -> %@", [error localizedDescription]); } else { CLPlacemark *placemark = [placemarks lastObject]; NSString* startAddressString = [NSString stringWithFormat:@"%@ %@ %@ %@ %@ %@", placemark.subThoroughfare, placemark.thoroughfare, placemark.postalCode, placemark.locality, placemark.administrativeArea, placemark.country]; NSLog(@"地址为:%@", startAddressString); annotation._city = placemark.locality; annotation._country = placemark.country; annotation._streetAddrerss = placemark.thoroughfare; annotation._zip = placemark.postalCode; annotation._state = placemark.name; } }]; [self._mapView addAnnotation:annotation]; [geoCoder release]; // 设置文本信息 NSString* stringLocation = [[NSString alloc] initWithFormat:@"%@\n%@", annotation.subtitle, annotation.title]; self._textLocationInfo.text = stringLocation; [stringLocation release]; [annotation release]; [self stopLocate]; } - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { NSLog(@"Authorization finished. status = %d", status); } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Locate Failed" message:[error description] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; NSLog(@"%@", [error description]); [alert show]; [alert release]; [self._locateActivityIndicator stopAnimating]; [self stopLocate]; } #pragma 实现协议MKMapViewDelegate // 画标注 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation; { MKPinAnnotationView* annotationView = (MKPinAnnotationView*)[self._mapView dequeueReusableAnnotationViewWithIdentifier:@"annotationView"]; if(annotationView == nil) { annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotationView"] autorelease]; } annotationView.canShowCallout = YES; annotationView.pinColor = MKPinAnnotationColorRed; annotationView.animatesDrop = YES; return annotationView; } @end
(实现标注协议的类见工程代码)
项目工程
时间: 2024-10-05 05:08:07