发现第三级没数据的时候,如果你在代码里没加【安全措施】,那也会导致崩溃,要在请求到第三级的数据后做下判断,如果个数为空,将该级对应的数据源置为nil。(其它两级的轮子最好也加判断)
最后,由于这是个封装的类,最终要得到选中的详细信息,可通过代理或block传值给controller。
又是你们最喜欢show code环节:
.h文件
#import <UIKit/UIKit.h>
//定制代理协议
@protocol ZLMAddressPickerViewDelegate <NSObject>
- (void)addressPickerViewDidSelected:(NSString *)areaName;//点击上方完成按钮的代理传回拼接好的选中地址
- (void)addressPickerViewDidClose;//点击关闭代理
@end
@interface ZLMAddressPickerView : UIView
@property (weak, nonatomic) id<ZLMAddressPickerViewDelegate> delegate;
@end
.m文件
#import "ZLMAddressPickerView.h"
#import "AFHttpUtils.h"
#import "AreaModel.h"
@interface ZLMAddressPickerView () <UIPickerViewDataSource, UIPickerViewDelegate>
@property (strong, nonatomic) UIPickerView *pickerView;
@property (strong, nonatomic) AreaModel *provBridge;
@property (strong, nonatomic) AreaModel *cityBridge;
@property (strong, nonatomic) AreaModel *areaBridge;
@property (copy, nonatomic) NSArray<Area *> * provDataArr;//省数组
@property (copy, nonatomic) NSArray<Area *> * cityDataArr;//市数组
@property (copy, nonatomic) NSArray<Area *> * areaDataArr;//区数组
@end
@implementation ZLMAddressPickerView
{
NSInteger _selectRow0;//记录第0个轮子的选择行
NSInteger _selectRow1;
NSInteger _selectRow2;
NSString *_areaString;//最后要传回的详细地址拼接字符串
Area *_proModel;//记录下选中省的数据
Area *_cityModel;
Area *_areaModel;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)setup {
_selectRow0 = 0;
_selectRow1 = 0;
_selectRow2 = 0;
self.backgroundColor = [UIColor whiteColor];
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), 44)];
toolbar.backgroundColor = [UIColor whiteColor];
[self addSubview:toolbar];
UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(selectAddressClose)];
UIBarButtonItem *completeItem = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(selectAddressComplete)];
UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
toolbar.items = @[closeItem, spaceItem, completeItem];
self.pickerView.frame = CGRectMake(0, 44, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - 44);
[self addSubview:self.pickerView];
[self downloadProv];
}
#pragma mark - http methods
/*省*/
- (void)downloadProv {
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary: @{@"id":@(0)} ];
[AFHttpUtils sendPostTaskWithUrl:[NSString stringWithFormat:@"%@/app/member/area",BASE_DOMAIN_URL] paramenters:dic successHandle:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"PROV:%@",responseObject);
self.provBridge = [AreaModel mj_objectWithKeyValues:responseObject];
if (self.provBridge.error_code==0) {
self.provDataArr=self.provBridge.data;
[self pickerView:self.pickerView didSelectRow:0 inComponent:0 ];//联动轮子1 必须得本轮有数据后才能触发didselect
[self.pickerView reloadAllComponents];
}
} errorHandle:^(NSError *error) {
}];
}
/*市*/
- (void)downloadCityWithId:(NSInteger)provId {
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary: @{@"id":@(provId)} ];
[AFHttpUtils sendPostTaskWithUrl:[NSString stringWithFormat:@"%@/app/member/area",BASE_DOMAIN_URL] paramenters:dic successHandle:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"CITY:%@",responseObject);
self.cityBridge = [AreaModel mj_objectWithKeyValues:responseObject];
if (self.cityBridge.error_code==0) {
self.cityDataArr=self.cityBridge.data;
[self.pickerView reloadComponent:1];
[self.pickerView selectRow:0 inComponent:1 animated:YES];//默认选择row0
[self pickerView:self.pickerView didSelectRow:0 inComponent:1 ];//联动轮子2 必须得本轮有数据后才能触发didselect
_cityModel = self.cityDataArr[_selectRow1];
[self downloadAreaWithId:_cityModel.area_id];
}
} errorHandle:^(NSError *error) {
}];
}
/*区*/
- (void)downloadAreaWithId:(NSInteger)cityId {
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary: @{@"id":@(cityId)} ];
[AFHttpUtils sendPostTaskWithUrl:[NSString stringWithFormat:@"%@/app/member/area",BASE_DOMAIN_URL] paramenters:dic successHandle:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"AREA:%@",responseObject);
self.areaBridge = [AreaModel mj_objectWithKeyValues:responseObject];
if (self.areaBridge.error_code==0&&self.areaBridge.data.count>0) {
self.areaDataArr=self.areaBridge.data;
}else{
self.areaDataArr=nil;
}
[self.pickerView reloadComponent:2];
[self.pickerView selectRow:0 inComponent:2 animated:YES];
[self pickerView:self.pickerView didSelectRow:0 inComponent:2 ];
} errorHandle:^(NSError *error) {
}];
}
#pragma mark - events response
- (void)selectAddressComplete {
[self.delegate addressPickerViewDidSelected:_areaString];
}
- (void)selectAddressClose {
[self.delegate addressPickerViewDidClose];
}
#pragma mark - UIPickerViewDataSource
//确定picker的轮子个数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3;
}
//确定picker的每个轮子的item数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (component==0) {
return self.provDataArr.count;
}else if(component==1){
return self.cityDataArr.count;
}else{
return self.areaDataArr.count;
}
}
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
return 36;
}
//确定每个轮子的每一项显示什么内容
- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component{
NSDictionary * attrDic = @{NSForegroundColorAttributeName:[UIColor blackColor],
NSFontAttributeName:[UIFont systemFontOfSize:12]};
Area *area;
if (component==0) {
area = self.provDataArr[row];
}else if(component==1){
area = self.cityDataArr[row];
}else{
area = self.areaDataArr[row];
}
NSAttributedString * attrString = [[NSAttributedString alloc] initWithString:area.name
attributes:attrDic];
return attrString;
}
//监听轮子的移动
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component==0) {
_selectRow0 = [pickerView selectedRowInComponent:0];
_selectRow1 = 0;
_selectRow2 = 0;
_proModel = self.provDataArr[_selectRow0];
[self downloadCityWithId:_proModel.area_id];
}else if(component==1){
_selectRow1 = [pickerView selectedRowInComponent:1];
_selectRow2 = 0;
_cityModel = self.cityDataArr[_selectRow1];
[self downloadAreaWithId:_cityModel.area_id];
}else{
_selectRow2 = [pickerView selectedRowInComponent:2];
if (self.areaDataArr&&self.areaDataArr.count>0) {
_areaModel = self.areaDataArr[_selectRow2];
}else{
_areaModel = nil;
}
}
if(_areaModel==nil){
_areaString = [NSString stringWithFormat:@"%@ %@",_proModel.name,_cityModel.name];
}else{
_areaString = [NSString stringWithFormat:@"%@ %@ %@",_proModel.name,_cityModel.name,_areaModel.name];
}
}
#pragma mark - getters and setters
- (UIPickerView *)pickerView {
if (_pickerView == nil) {
_pickerView = [[UIPickerView alloc] init];
_pickerView.delegate = self;
_pickerView.dataSource = self;
}
return _pickerView;
}
@end










