·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> app软件开发 >> IOS开发 >> IOS实现自动定位和手动选择城市功能

IOS实现自动定位和手动选择城市功能

作者:佚名      IOS开发编辑:admin      更新时间:2022-07-23

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 <UIKit/UIKit.h>

@interface AreaPickerCheckView : UIView<UipickerViewDataSource,UIPickerViewDelegate>

- (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 ()<CLLocationManagerDelegate,MAMapViewDelegate,AMapSearchDelegate>

{

    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 欢迎加入一起讨论技术哦