IOS实现自动定位和手动选择城市功能
阅读原文时间:2023年07月10日阅读:2

IOS自动定位使用的是高德地图SDK

在高德开放平台http://lbs.amap.com/api/ios-sdk/down/ 下载2D地图SDK和搜索SDK

将SDK导入工程内 按照高德的配置说明进行配置项目

最后需要提醒 在高德的SDK中有些文件夹使用的是快捷方式, 如果你在你本地的工程编译通过, 但可能在你的服务端自动打包的时候不能自动编译通过

需要将那些快捷方式的文件夹用真实文件夹替换掉就可以了。

在工程中导入

#import "MAMapKit/MAMapKit.h"

#import "AMapSearchKit/AMapCommonObj.h"

#import "AMapSearchKit/AMapSearchAPI.h"

在Controller中使用初始化地图服务

#pragma mark MAMAP init AND 定位回调

  • (void)initMap
    {

    if (![CLLocationManager locationServicesEnabled]) {
    [PXAlertView showAlertWithTitle:@"提示" message:[NSString stringWithFormat:@"请开启定位:设置 > 隐私 > 位置 > 定位服务"] completion:^(BOOL cancelled, NSInteger buttonIndex) {
    }];
    return;
    }
    else if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
    [PXAlertView showAlertWithTitle:@"提示" message:[NSString stringWithFormat:@"定位失败,请开启定位:设置 > 隐私 > 位置 > 定位服务 下 应用"] completion:^(BOOL cancelled, NSInteger buttonIndex) {
    }];
    return;
    }
    [MAMapServices sharedServices].apiKey = MAMAP_APPKEY;//高德KEY
    _mapView = [[MAMapView alloc] init];
    _mapView.delegate = self;
    _mapView.showsUserLocation = YES;
    //[_mapView setUserTrackingMode:MAUserTrackingModeFollowWithHeading animated:YES];

    point = [[AMapGeoPoint alloc] init];
    _search = [[AMapSearchAPI alloc] initWithSearchKey:MAMAP_APPKEY
    Delegate:self];
    regeoRequest = [[AMapReGeocodeSearchRequest alloc] init];
    regeoRequest.searchType = AMapSearchType_ReGeocode;
    regeoRequest.radius = 50;
    regeoRequest.requireExtension = YES;
    }

// 定位回调

  • (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation
    {
    if (updatingLocation) {

    point.latitude  = userLocation.coordinate.latitude;  
    point.longitude = userLocation.coordinate.longitude;
    
    regeoRequest.location = \[AMapGeoPoint locationWithLatitude:point.latitude  
                                                     longitude:point.longitude\];  
    // 发起逆地理编码  
    \[\_search AMapReGoecodeSearch:regeoRequest\];  
     \_mapView.showsUserLocation  =NO;

    }
    }
    // 逆地理编码回调

  • (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
    {
    if (response.regeocode != nil) {

    NSString \*province=response.regeocode.addressComponent.province;  
    NSString \*city=response.regeocode.addressComponent.city;  
    NSString \*district=response.regeocode.addressComponent.district;  
    NSString \*value=nil;  
    NSString \*key=nil;
    
    NSMutableArray \*cityArrayTemp=nil;  
    for (AreaModel \*model in provinceArray) {  
        if (\[model.value isEqualToString:province\]) {  
            cityArrayTemp=\[NSMutableArray arrayWithArray:model.children\];  
        }  
    }  
    NSMutableArray \*districtArryTemp=nil;  
    if (cityArrayTemp) {  
        if (city.length>0) {  
            for (AreaModel \*cityModel in cityArrayTemp) {  
                if (\[cityModel.value isEqualToString:city\]) {  
                    districtArryTemp=\[NSMutableArray arrayWithArray:cityModel.children\];  
                }  
            }  
        }  
        else{  
            //直辖市  
            for (AreaModel \*cityModel in cityArrayTemp) {  
                if (\[cityModel.value isEqualToString:district\]) {  
                    value=cityModel.value;  
                    key=cityModel.key;  
                }  
            }  
        }  
    }  
    if (districtArryTemp) {  
        for (AreaModel \*provinceModel in districtArryTemp) {  
            if (\[provinceModel.value isEqualToString:district\]) {  
                value=provinceModel.value;  
                key=provinceModel.key;  
            }  
        }  
    }  
    self.keyCode=key;  
    \[self.checkCityButton setTitle:\[NSString stringWithFormat:@"%@%@%@",province,city,district\] forState:UIControlStateNormal\];

    }
    }

封装省市县 三级选择控件

#import

@interface AreaPickerCheckView : UIView

  • (instancetype)initWithFrame:(CGRect)frame andDataSource:(NSArray *)dataSource dismissCompletion:(void (^)(BOOL isCancelClick , NSString *area , NSString *code))completion;

@end

#import "AreaPickerCheckView.h"
#import "AreaModel.h"

@interface AreaPickerCheckView()
{
NSArray *provinceArray;
NSArray *cityArray;
NSArray *areaArray;
void (^completionBlock)(BOOL isCancelClick , NSString *area , NSString *code);
}

@property(nonatomic,strong)NSArray *dataSource;
@property(nonatomic,strong)UIPickerView *pickerView;

@end

@implementation AreaPickerCheckView

  • (instancetype)initWithFrame:(CGRect)frame andDataSource:(NSArray *)dataSource dismissCompletion:(void (^)(BOOL, NSString *, NSString *))completion
    {
    self = [super initWithFrame:frame];
    if (self) {
    completionBlock = [completion copy];
    self.dataSource = dataSource;
    [self createUI];// Initialization code
    }
    return self;
    }

  • (void)createUI {

    provinceArray = self.dataSource;

    AreaModel *model = [self.dataSource firstObject];

    cityArray = model.children;

    AreaModel *model1 = [model.children firstObject];

    areaArray = model1.children;

    self.pickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, 25, self.frame.size.width, self.frame.size.height-25)];
    self.pickerView.dataSource = self;
    self.pickerView.delegate = self;
    [self addSubview:self.pickerView];

    UIButton *confirmBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    confirmBtn.frame = CGRectMake(Main_Screen_Width - 50, 5, 40, 20);
    [confirmBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [confirmBtn setTitle:@"确定" forState:UIControlStateNormal];
    [confirmBtn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    confirmBtn.tag = 100;
    [self addSubview:confirmBtn];

    UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    cancelBtn.frame = CGRectMake(10, 5, 40, 20);
    cancelBtn.tag = 101;
    [cancelBtn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    [cancelBtn setTitle:@"取消" forState:UIControlStateNormal];
    [cancelBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [self addSubview:cancelBtn];

}

#pragma mark dataSouce

  • (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 3;
    }

  • (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    if (component == 0) {
    return provinceArray.count;
    }else if (component == 1) {
    return cityArray.count;
    }
    return areaArray.count;
    }
    #pragma mark delegate

  • (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    AreaModel *model = nil;
    if (component == 0) {
    model = provinceArray[row];
    }else if (component == 1) {
    model = cityArray[row];
    }else if (component == 2) {
    model = areaArray[row];
    }
    return model.value;
    }

  • (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    if (component == 0) {
    AreaModel *model = provinceArray[row];
    cityArray = model.children;
    areaArray = [[cityArray firstObject] children];

    \[self.pickerView reloadComponent:1\];  
    \[self.pickerView reloadComponent:2\];

    }else if (component == 1) {
    AreaModel *model = cityArray[row];
    areaArray = model.children;
    [self.pickerView reloadComponent:2];
    }
    }

  • (void)btnClick:(UIButton *)btn {
    BOOL isCancel = NO;
    switch (btn.tag) {
    case 100:

        break;  
    case 101:  
        isCancel = YES;  
        completionBlock(YES,nil,nil);  
        return;  
        break;
    
    default:  
        break;  

    }

    NSString *str = nil;
    NSString *codeStr = nil;

    AreaModel *model = provinceArray[[self.pickerView selectedRowInComponent:0]];
    str = model.value;
    AreaModel *model1 = cityArray[[self.pickerView selectedRowInComponent:1]];
    str = [str stringByAppendingString:model1.value];
    codeStr = model1.key;
    if (areaArray.count > 0) {
    AreaModel *model2 = areaArray[[self.pickerView selectedRowInComponent:2]];
    str = [str stringByAppendingString:model2.value];
    codeStr = model2.key;
    }

    completionBlock(isCancel,str,codeStr);
    }

@end

在Controller中使用地理位置选择控件

@interface CityCheckController ()

{

NSString *_sessionKey;

NSString *_code;

AMapGeoPoint *point;

AMapReGeocodeSearchRequest *regeoRequest;

NSArray *provinceArray;

}

@property (weak, nonatomic) IBOutlet UITextField *areaTF;

@property(nonatomic,strong) MAMapView *mapView;

@property(nonatomic,strong) AMapSearchAPI *search;

- (void)viewDidLoad {
[super viewDidLoad];

NSArray \*models = \[AreaModel objectArrayWithFilename:@"area.plist"\];  
provinceArray=models;  
AreaPickerCheckView \*picker = \[\[AreaPickerCheckView alloc\]initWithFrame:CGRectMake(0, 0, Main\_Screen\_Width, 216) andDataSource:models dismissCompletion:^(BOOL isCancelClick, NSString \*area, NSString \*code) {  
    \[self.areaTF resignFirstResponder\];  
    if (isCancelClick) {  
        return;  
    }else{  
        self.areaTF.text = area;  
        \_code = code;  
    }  
}\];  
self.areaTF.inputView = picker;  
\[self initMap\];

}

IOS开发技术交流QQ群:491355147 欢迎加入一起讨论技术哦