iOS系統(tǒng)自帶的MapView基本使用
感覺(jué)用第三方地圖只需要根據(jù)現(xiàn)成的文檔走就基本上很輕松實(shí)現(xiàn)短绸,所以想自己使用一下系統(tǒng)自帶的方法實(shí)現(xiàn)一些地圖的基本功能,網(wǎng)上查閱了一下實(shí)現(xiàn)了基本功能,和初學(xué)者共同進(jìn)步
主要功能
- 定位到用戶當(dāng)前位置
- 顯示 附近位置
- 長(zhǎng)按地圖選點(diǎn)
- 手動(dòng)搜索位置
效果圖如下:
1 定位 當(dāng)前用戶位置
首先得在infoplist
文件里面添加NSLocationWhenInUseUsageDescription
字段來(lái)讓系統(tǒng)提示授權(quán)應(yīng)用定位服務(wù)
其次就是判斷是否有定位服務(wù)代碼了
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager=[[CLLocationManager alloc]init];;
//判斷當(dāng)前設(shè)備定位服務(wù)是否打開(kāi)
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"設(shè)備尚未打開(kāi)定位服務(wù)");
}
//判斷當(dāng)前設(shè)備版本大于iOS8以后的話執(zhí)行里面的方法
if ([UIDevice currentDevice].systemVersion.floatValue >=8.0) {
//持續(xù)授權(quán)
// [locationManager requestAlwaysAuthorization];
//當(dāng)用戶使用的時(shí)候授權(quán)
[self.locationManager requestWhenInUseAuthorization];
}
if ([CLLocationManager authorizationStatus] ==kCLAuthorizationStatusDenied) {
NSString *message = @"您的手機(jī)目前未開(kāi)啟定位服務(wù)缅茉,如欲開(kāi)啟定位服務(wù)车酣,請(qǐng)至設(shè)定開(kāi)啟定位服務(wù)功能";
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"無(wú)法定位" message:message delegate:nil cancelButtonTitle:@"確定" otherButtonTitles: nil];
[alertView show];
}
//請(qǐng)求授權(quán)
// [locationManager requestWhenInUseAuthorization];
/*
MKUserTrackingModeNone 不進(jìn)行用戶位置跟蹤
MKUserTrackingModeFollow 跟蹤用戶的位置變化
MKUserTrackingModeFollowWithHeading 跟蹤用戶位置和方向變化
*/
//設(shè)置用戶的跟蹤模式
self.mapView.userTrackingMode=MKUserTrackingModeFollow;
/*
MKMapTypeStandard 標(biāo)準(zhǔn)地圖
MKMapTypeSatellite 衛(wèi)星地圖
MKMapTypeHybrid 鳥(niǎo)瞰地圖
MKMapTypeSatelliteFlyover
MKMapTypeHybridFlyover
*/
self.mapView.mapType=MKMapTypeStandard;
//實(shí)時(shí)顯示交通路況
self.mapView.showsTraffic=NO;
//設(shè)置代理
self.mapView.delegate=self;
[self initMapView];
[self initSearch];
[self initTableView];
}
其次是初始化地圖顯示用戶當(dāng)前位置
pragma mark - 初始化
- (void)initMapView
{
_mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0,54, SCREEN_WIDTH, SCREEN_HEIGHT - CELL_HEIGHT*CELL_COUNT)];
_mapView.delegate = self;
// 不顯示羅盤
_mapView.showsCompass = NO;
// 不顯示比例尺
_mapView.showsScale = NO;
MKCoordinateSpan span=MKCoordinateSpanMake(0.021251, 0.016093);
[self.mapView setRegion:MKCoordinateRegionMake(self.mapView.userLocation.coordinate, span) animated:YES];
// 開(kāi)啟定位
_mapView.showsUserLocation = YES;
[self.view addSubview:_mapView];
}
/**
* 跟蹤到用戶位置時(shí)會(huì)調(diào)用該方法
* @param mapView 地圖
* @param userLocation 大頭針模型
*/
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
if (userLocation&& !_isFirstLocated) {
//創(chuàng)建編碼對(duì)象
CLGeocoder *geocoder=[[CLGeocoder alloc]init];
//反地理編碼
[geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (error!=nil || placemarks.count==0) {
return ;
}
//獲取地標(biāo)
CLPlacemark *placemark=[placemarks firstObject];
//設(shè)置標(biāo)題
userLocation.title=placemark.locality;
//設(shè)置子標(biāo)題
userLocation.subtitle=placemark.name;
_dangQiang = placemark;
[self fetchNearbyInfo:userLocation.location.coordinate.latitude andT:userLocation.location.coordinate.longitude];
}];
[_mapView setCenterCoordinate:CLLocationCoordinate2DMake(userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude)];
_isFirstLocated = YES;
}
}
2 顯示附近位置
根據(jù)傳入的坐標(biāo)顯示附近的位置外遇,這里要說(shuō)下系統(tǒng)一次性只會(huì)返回固定十個(gè)數(shù)據(jù)的數(shù)組,要說(shuō)明的一點(diǎn)是里面有個(gè)requst.naturalLanguageQuery = @"place"
這句話 傳的字段是place
這個(gè)字段系統(tǒng)會(huì)返回附近幾個(gè)地址你可以傳任何地面建筑類型的英文進(jìn)去都可以被識(shí)別搜索比如醫(yī)院的英文單詞hospital
系統(tǒng)只會(huì)返回附近的醫(yī)院女阀,見(jiàn)如下代碼:
- (void)fetchNearbyInfo:(CLLocationDegrees )latitude andT:(CLLocationDegrees )longitude
{
CLLocationCoordinate2D location=CLLocationCoordinate2DMake(latitude, longitude);
MKCoordinateRegion region=MKCoordinateRegionMakeWithDistance(location, 1 ,1 );
MKLocalSearchRequest *requst = [[MKLocalSearchRequest alloc] init];
requst.region = region;
requst.naturalLanguageQuery = @"place"; //想要的信息
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:requst];
[self.dataRrray removeAllObjects];
[localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error){
if (!error)
{
for (MKMapItem *map in response.mapItems) {
NSLog(@"%@",map.name);
}
[self.dataRrray addObjectsFromArray:response.mapItems];
[self.tableView reloadData];
//
}
else
{
//
}
}];
}
3 長(zhǎng)按地圖選點(diǎn)
說(shuō)白了就是在MapVIew上面加一個(gè)長(zhǎng)按手勢(shì)添加大頭針宅荤,為了避免篇幅過(guò)程該功能就不貼代碼描述詳情可以見(jiàn)文章末尾Demo
4 手動(dòng)搜索地址
這個(gè)功能還是比較常見(jiàn)的的嘿嘿屑迂,我也是網(wǎng)上參考別人的實(shí)現(xiàn)的,各位看官看看以下代碼都差不多就會(huì)了,就是調(diào)用一個(gè)方法的事??
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
CLGeocoder *geocoder=[[CLGeocoder alloc]init];
//判斷是否為空
if (searchText.length ==0) {
return;
}
[self.searchResultArray removeAllObjects];
[geocoder geocodeAddressString:searchText completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (error!=nil || placemarks.count==0) {
return ;
}
//創(chuàng)建placemark對(duì)象
self.searchResultArray = [[NSMutableArray alloc]initWithArray:placemarks];
//CLPlacemark *placemark=[self.searchResultArray firstObject];
[self.searchDisplayController.searchResultsTableView reloadData];
}
5 MapView性能優(yōu)化問(wèn)題
相信很多初學(xué)者和我一樣適用系統(tǒng)自帶的地圖時(shí)占用內(nèi)存會(huì)暴漲冯键,我做完上述功能也只網(wǎng)上查了不少資料有些大神說(shuō)把地圖繪制成圖片顯示等等我看了有點(diǎn)蒙蔽惹盼,找到了兩個(gè)簡(jiǎn)單的優(yōu)化方法,稍微優(yōu)化了一點(diǎn)點(diǎn)內(nèi)存總比沒(méi)有優(yōu)化強(qiáng)呀??惫确,有什么更好的方法可以告訴我學(xué)習(xí)下嘿嘿
/#pragma mark - 內(nèi)存優(yōu)化
//在移除self.map的同時(shí)手报,重新加載mapView,兩行代碼就可以達(dá)到釋放內(nèi)存的效果
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
[self.mapView removeFromSuperview];
[self.view addSubview:mapView];
[self applyMapViewMemoryHotFix];
}
- (void)dealloc {
self.mapView.showsUserLocation = NO;
self.mapView.userTrackingMode = MKUserTrackingModeNone;
[self.mapView.layer removeAllAnimations];
[self.mapView removeAnnotations:self.mapView.annotations];
[self.mapView removeOverlays:self.mapView.overlays];
[self.mapView removeFromSuperview];
self.mapView.delegate = nil;
self.mapView = nil;
}
- (void)applyMapViewMemoryHotFix{
switch (self.mapView.mapType) {
case MKMapTypeHybrid:
{
self.mapView.mapType = MKMapTypeStandard;
}
break;
case MKMapTypeStandard:
{
self.mapView.mapType = MKMapTypeHybrid;
}
break;
default:
break;
}
self.mapView.mapType = MKMapTypeStandard;
}
結(jié)束語(yǔ)
慢慢學(xué)習(xí)iOS共同進(jìn)步吧改化,有什么問(wèn)題和好的建議給我留個(gè)言掩蛤,碼字不易點(diǎn)個(gè)喜歡吧可以的話,附上Demo地址
寫(xiě)完又發(fā)現(xiàn)搜索按鈕旁邊的取消按鈕為英文cancel
,如果我們不寫(xiě)一行代碼怎么讓它變?yōu)橹形?code>取消呢陈肛,那就是在info.plistLocalization native development region
這一項(xiàng)改為en,China
,那么如果用戶把手機(jī)語(yǔ)言設(shè)成英文, 那么顯示的就是英文, 設(shè)置成中文,那么顯示的就是中文.