开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情
前言
采用UIPickerView实现,核心方法czh_getData:构建数据模型,先从网络进行获取数据,如果获取失败,直接取本地的city.json
- 选择省市区效果
- 选择省市
使用方法:
回调参数包括选中的省(provinceId)、市ID(cityId)区ID(areaid)
[AddressPickerView areaPickerViewWithProvince:self.viewModel.AddressPickerModel.province city:self.viewModel.AddressPickerModel.city provinceId:self.viewModel.AddressPickerModel.provinceId cityId:self.viewModel.AddressPickerModel.cityId cityBlock:^(NSString *province, NSString *city , NSString* provinceId,NSString* cityId) {
weakSelf.viewModel.AddressPickerModel.province = province;
weakSelf.viewModel.AddressPickerModel.city = city;
weakSelf.viewModel.AddressPickerModel.provinceId = provinceId;
weakSelf.viewModel.AddressPickerModel.cityId = cityId;
NSString* Title = [NSString stringWithFormat:@"%@%@",province,city] ;
weakSelf.viewModel.ProductplaceModel.content = Title ;
[self.viewModel.reloadProductPlaceModelSubject sendNext:nil];
NSLog(@"更新信息 provinceId:%@ cityId:%@",provinceId,cityId);
} showType:CZHAddressPickerViewTypeCity];
I 、核心代码
1.1 AddressPickerView的构建数据模型
从网络进行获取数据,如果获取失败,直接取本地的city.json
- (void)czh_getData {
NSArray *tmp = [QCTAreaListTool getAreaList];
if (tmp.count >0) {// 修改为不取本地的,数据量太大了
self.dataSource = tmp;
}else{//获取本地数据
NSString *path = [[NSBundle mainBundle] pathForResource:@"city.json" ofType:nil];
NSArray *array = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:path] options:NSJSONReadingMutableLeaves error:nil];
self.dataSource = array;
}
NSMutableArray * tempArray = [NSMutableArray array];
NSMutableArray * tempIDArray = [NSMutableArray array];
for (NSDictionary * tempDic in self.dataSource) {
[tempArray addObject:tempDic[areaName]];
[tempIDArray addObject:tempDic[areaId]];
}
//省
self.provinceArray = [tempArray copy];
self.provinceIDArray = [tempIDArray copy];
//市
self.cityArray = [self getCityNamesFromProvinceIndex:0];
self.cityIDArray = [self getCityIDFromProvinceIndex:0];
//区
self.areaArray = [self getAreaNamesFromProvinceIndex:0 cityIndex:0];
//areaCodeArray
self.areaCodeArray = [self getAreaareaCodeFromProvinceIndex:0 cityIndex:0];
//如果没有传入默认选中的省市区,默认选中各个数组的第一个
if (!self.selectProvince.length) {
self.selectProvince = [self.provinceArray firstObject];
self.selectProvinceID = [self.provinceIDArray firstObject];
}
if (!self.selectCity.length) {
self.selectCity = [self.cityArray firstObject];
self.selectcityId = self.cityIDArray.firstObject;
}
if (!self.selectArea.length) {
self.selectArea = [self.areaArray firstObject];
self.selectAreaCode = [self.areaCodeArray firstObject];
}
NSInteger provinceIndex = 0;
NSInteger cityIndex = 0;
NSInteger areaIndex = 0;
BOOL isfindarea = NO;// 是否定位到上一次选择的地址
// 如果上次选择的不是同一数据源,不是统一接口/Area/FindAnyAll返回数据, 这个时候,就无法直接定位到对应的选择地址上。(例如选择的是福建省,而数据源中确是福建)
for (NSInteger p = 0; p < self.provinceArray.count; p++) {
if ([self.provinceArray[p] isEqualToString:self.selectProvince]) {
self.selectProvinceIndex = p;
provinceIndex = p;
self.cityArray = [self getCityNamesFromProvinceIndex:p];
self.cityIDArray = [self getCityIDFromProvinceIndex:p];
if(self.showType == CZHAddressPickerViewTypeProvince){
isfindarea = YES;
}
for (NSInteger c = 0; c < self.cityArray.count; c++) {
if ([self.cityArray[c] isEqualToString:self.selectCity]) {
cityIndex = c;
self.areaArray = [self getAreaNamesFromProvinceIndex:p cityIndex:c];
self.areaCodeArray = [self getAreaareaCodeFromProvinceIndex:p cityIndex:c];
if(self.showType == CZHAddressPickerViewTypeCity){
isfindarea = YES;
}
for (NSInteger a = 0; a < self.areaArray.count; a++) {
if ([self.areaArray[a] isEqualToString:self.selectArea]) {
areaIndex = a;
if(self.showType == CZHAddressPickerViewTypeArea){
isfindarea = YES;
}
}
}
}
}
}
}
// 处理没有匹配到的情况。 如果修改地址没有从接口/Area/FindAnyAll返回的数据,找到对应记录。 这个时候,就无法直接定位到对应的选择地址上。
//
if(isfindarea == NO){
self.selectProvince = [self.provinceArray firstObject];
self.selectProvinceID = [self.provinceIDArray firstObject];
self.selectCity = [self.cityArray firstObject];
self.selectcityId = self.cityIDArray.firstObject;
self.selectArea = [self.areaArray firstObject];
self.selectAreaCode = [self.areaCodeArray firstObject];
}
if (self.showType == CZHAddressPickerViewTypeProvince) {
[self.pickerView selectRow:provinceIndex inComponent:0 animated:YES];
} else if (self.showType == CZHAddressPickerViewTypeCity) {
[self.pickerView selectRow:provinceIndex inComponent:0 animated:YES];
[self.pickerView selectRow:cityIndex inComponent:1 animated:YES];
} else if (self.showType == CZHAddressPickerViewTypeArea) {
[self.pickerView selectRow:provinceIndex inComponent:0 animated:YES];
[self.pickerView selectRow:cityIndex inComponent:1 animated:YES];
[self.pickerView selectRow:areaIndex inComponent:2 animated:YES];
}
}
1.2 didSelectRow
#pragma mark - ******** 滚动省选择市区
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0) {//选择省
self.selectProvinceIndex = row;
if (self.showType == CZHAddressPickerViewTypeProvince) {
self.selectProvince = self.provinceArray[row];
self.selectCity = @"";
self.selectArea = @"";
} else if (self.showType == CZHAddressPickerViewTypeCity) {
self.cityArray = [self getCityNamesFromProvinceIndex:row];
// 重新获取self.cityIDArray
self.cityIDArray = [self getCityIDFromProvinceIndex:row];
[self.pickerView reloadComponent:1];// 市
[self.pickerView selectRow:0 inComponent:1 animated:YES];// 默认选中
self.selectProvince = self.provinceArray[row];
// 存储self.selectProvinceID
self.selectProvinceID = self.provinceIDArray[row];
self.selectCity = self.cityArray[0];
self.selectcityId = self.cityIDArray.count? self.cityIDArray[0]:@"";
self.selectArea = @"";
} else if (self.showType == CZHAddressPickerViewTypeArea) {
self.cityArray = [self getCityNamesFromProvinceIndex:row];
self.cityIDArray = [self getCityIDFromProvinceIndex:row];
self.areaArray = [self getAreaNamesFromProvinceIndex:row cityIndex:0];
self.areaCodeArray = [self getAreaareaCodeFromProvinceIndex:row cityIndex:0];
[self.pickerView reloadComponent:1];
[self.pickerView selectRow:0 inComponent:1 animated:YES];
[self.pickerView reloadComponent:2];
[self.pickerView selectRow:0 inComponent:2 animated:YES];
self.selectProvince = self.provinceArray[row];
self.selectProvinceID = self.provinceIDArray[row];
self.selectcityId = self.cityIDArray.count? self.cityIDArray[0]:@"";
self.selectCity = self.cityArray.count?self.cityArray[0]:@"";
self.selectArea = self.areaArray.count?self.areaArray[0]:@"";
self.selectAreaCode = self.areaCodeArray.count?self.areaCodeArray[0]:@"";
}
}else if (component == 1){//选择市
if (self.showType == CZHAddressPickerViewTypeCity) {
self.selectCity = self.cityArray[row];
self.selectArea = @"";
} else if (self.showType == CZHAddressPickerViewTypeArea) {
self.areaArray = [self getAreaNamesFromProvinceIndex:self.selectProvinceIndex cityIndex:row];
self.areaCodeArray = [self getAreaareaCodeFromProvinceIndex:self.selectProvinceIndex cityIndex:row];
[self.pickerView reloadComponent:2];
[self.pickerView selectRow:0 inComponent:2 animated:YES];
self.selectCity = self.cityArray[row];
self.selectcityId = self.cityIDArray[row];
self.selectArea = self.areaArray.count?self.areaArray[0]:@"";
self.selectAreaCode = self.areaCodeArray.count?self.areaCodeArray[0]:@"";
}
}else if (component == 2){//选择区
if (self.showType == CZHAddressPickerViewTypeArea) {
if(self.areaArray.count == 0){
self.selectArea = @" ";
self.selectAreaCode = @" ";
}else{
self.selectArea = self.areaArray[row];
self.selectAreaCode = self.areaCodeArray[row];
}
}
}
}
1.3 初始化方法
#pragma mark - ******** 选择省和市
+ (instancetype)newaddressPickerViewWithProvince:(NSString *)province city:(NSString *)city provinceId:(NSString*)provinceId cityId:(NSString*)cityId cityBlock:(void(^)(NSString *province, NSString *city ,NSString* provinceId,NSString *cityId))cityBlock showType:(CZHAddressPickerViewType)showType{
CZHAddressPickerView *_view = [[CZHAddressPickerView alloc] init];
_view.showType = showType;
_view.selectProvince = province;
_view.selectProvinceID = provinceId;
_view.selectCity = city;
_view.selectcityId = cityId;
_view.cityidBlock = cityBlock;
#pragma mark - ******** 获取原始数据
[_view czh_getData];
[_view showView];
return _view;
}
1.4 工具方法: 获取每个component的数据
1.4.1 获取城市数据
- 根据row获取城市id数组
//获取城市id数组
- (NSArray *)getCityIDFromProvinceIndex:(NSInteger)provinceIndex
{
NSArray * tempArr = [self.dataSource[provinceIndex] objectForKey:cities];
NSMutableArray * cityArray = [NSMutableArray array];
for (NSDictionary * valueDic in tempArr) {
[cityArray addObject:valueDic[self.areaId]];
}
return [cityArray copy];
}
- 获取城市数组
//获取城市数组
- (NSArray *)getCityNamesFromProvinceIndex:(NSInteger)provinceIndex
{
NSArray * tempArr = [self.dataSource[provinceIndex] objectForKey:cities];
NSMutableArray * cityArray = [NSMutableArray array];
for (NSDictionary * valueDic in tempArr) {
// for (int i = 0; i < valueDic.allKeys.count; i ++) {
[cityArray addObject:valueDic[areaName]];
// }
}
return [cityArray copy];
}
1.4.2 获取区域数据
- 获取区域ID数组
//获取区域ID数组
- (NSArray *)getAreaareaCodeFromProvinceIndex:(NSInteger)provinceIndex cityIndex:(NSInteger)cityIndex
{
NSArray * tempArr = [self.dataSource[provinceIndex] objectForKey:cities];
NSMutableArray * array = [NSMutableArray array];
if (tempArr.count) {
NSArray * cityArr = [tempArr[cityIndex] objectForKey:cities];
for (NSDictionary * valueDic in cityArr) {
[array addObject:valueDic[self.areaId]];//areaCode
}
return [array copy];
}else{
return @[];
}
}
-获取区域数组
- (NSArray *)getAreaNamesFromProvinceIndex:(NSInteger)provinceIndex cityIndex:(NSInteger)cityIndex
{
NSArray * tempArr = [self.dataSource[provinceIndex] objectForKey:cities];
NSMutableArray * array = [NSMutableArray array];
if (tempArr.count) {
NSArray * cityArr = [tempArr[cityIndex] objectForKey:cities];
for (NSDictionary * valueDic in cityArr) {
[array addObject:valueDic[areaName]];
}
return [array copy];
}else{
return @[];
}
}
1.4.3获取省份数据,用于选择组件视图
NSMutableArray * tempArray = [NSMutableArray array];
NSMutableArray * tempIDArray = [NSMutableArray array];
for (NSDictionary * tempDic in self.dataSource) {
[tempArray addObject:tempDic[areaName]];
[tempIDArray addObject:tempDic[self.areaId]];
}
//省
self.provinceArray = [tempArray copy];
self.provinceIDArray = [tempIDArray copy];
II、设置UIPickerView的选中横线的颜色(设置白色可达到隐藏的效果)
kunnan.blog.csdn.net/article/det…
see also
city.json 数据
- city.json
[{
"parentId": "1",
"areaSN": "",
"postCode": "",
"sort": 3,
"areaCode": "120000",
"id": "4",
"quanPin": "tianjin",
"childItems": [{
"parentId": "4",
"areaSN": "022",
"postCode": "300000",
"sort": 1,
"areaCode": "120100",
"id": "305",
"quanPin": "tianjin",
"childItems": [{
"parentId": "305",
"areaSN": "",
"postCode": "300000",
"sort": 1,
"areaCode": "120101",
"id": "311",
"quanPin": "heping",
"childItems": null,
"jianPin": "hp",
"areaName": "和平区"
},
- city.plist