通常情况下,我们实现地区三级联动,只需要加载一个地址plist文件,通过UIPickerView展示出来即可。但有时候需求的不变性,我们需要去做更多的处理,例如当我们需要获取开通省市区的地址id,省市区是由后台返回的数据,这个时候我们就需要对各级数据进行判空处理,并对数组进行越界保护。大致效果和加载本地没什么区别,只是数据经过了后台筛选,大致如下:
首先我们需要新建三个数组,分别对应省市区,当然我们最好给这三个数组指定数据类型,即确定为包含某数据模型的可变数组,数据转换模型不太懂得话,可以接下来讨论。下面我贴上三级联动数据结构和我建的数组与模型结构,数据模型:
城市model:
新建数组:
后台数据结构:
后台数据很多,我这里只是展示一个大体的数据结构。
当我们请求到数据过后,就需要对数据进行模型转换并存进相应的数组,
首先我们需要对数据最外层省进行数据转换,获取到省级地区过后,当省级地区个数大于0的时候,我们要遍历获取第一个省市下面的所有的市,用于第一次打开pickerview时候的展示,然后再对第一个市下面的所有区域进行遍历,获取到所有的区。
这里数据我们已经处理完毕,在pickerview中,每一列的行数,与每一行展示的string,直接使用相应的数组对应,就好,不需要过多的讲解。关键在于滑动的时候,我们需要再次去对数组进行赋值,删除数组的旧值,将重新获取到的新值添加进去。主要过程就是,滑动的时候选择相应的省,删除原有的数组里面所有的市,然后遍历当前的省,对数组进行重新赋值,区域亦是如此。滑动市级分类的时候,就删除原有的区域,遍历当前市区,对区域数组重新赋值,获取当前滑动的区域ID。
` switch (component) {
case 0:
proStr = proArray[row].name;
proID = proArray[row].ID;
cityArray = [NSMutableArray array];
quArray = [NSMutableArray array];
for (id city in proArray[row].sub_areas) {
TDCityModel *citymodel = [TDCityModel mj_objectWithKeyValues:city];
[cityArray addObject:citymodel];
}
cityStr = @"";
cityID = @"";
if (cityArray.count > 0) {
cityStr = cityArray[0].name;
cityID = cityArray[0].ID;
if (cityArray[0].sub_areas.count>0) {
for (id sub in cityArray[0].sub_areas) {
TDCityModel *citymodel = [TDCityModel mj_objectWithKeyValues:sub];
[quArray addObject:citymodel];
}
}
}
subStr = @"";
subID = @"";
if (quArray.count > 0) {
subStr = quArray[0].name;
subID = quArray[0].ID;
}
[threepicker reloadComponent:1];
[threepicker reloadComponent:2];
[threepicker selectRow:0 inComponent:1 animated:YES];
[threepicker selectRow:0 inComponent:2 animated:YES];
break;
case 1:
subStr = @"";
subID = @"";
// if (row>=cityArray.count) {
// return;
// }
cityStr = cityArray[row].name;
cityID = cityArray[row].ID;
[quArray removeAllObjects];
if (cityArray[row].sub_areas.count>0) {
for (id sub in cityArray[row].sub_areas) {
TDCityModel *citymodel = [TDCityModel mj_objectWithKeyValues:sub];
[quArray addObject:citymodel];
}
}
if (quArray.count>0) {
subStr = quArray[0].name;
subID = quArray[0].ID;
}
[threepicker reloadComponent:2];
[threepicker selectRow:0 inComponent:2 animated:YES];
break;
case 2:
if (row>=quArray.count) {
return;
}
subStr = [quArray objectAtIndex:row].name;
subID = [quArray objectAtIndex:row].ID;
default:
break;
}
`
大致流程就是这样的,如果有什么不懂,可以留言交流,有更好的优化建议,也欢迎指出,后期会整理出逻辑更清晰的demo,以供大家参考。