一般的项目中都会有一个选择地址的需求,系统的UIDatePicker肯定是不够的,找了个比较好用的库
ActionSheetCustomPicker
github地址:ActionSheetCustomPicker地址,需要的进去看看
咱们要的效果如下:
先来屡屡思路,首先,咱们用cocopods导入两个需要的库 根据需要导入头文件到控制器
pod'ActionSheetPicker-3.0'
pod'MJExtension'
然后咱们肯定要有两个界面如下
第一个 第二个界面
第一个界面
@property (weak, nonatomic) IBOutlet UILabel *address; // 显示具体地址 @property (nonatomic,strong) NSArray *sections; // 选择的三个index数组 省 市 县
@interface ViewController () <ActionSheetCustomPickerDelegate> @property (nonatomic,strong) NSArray *addressArr; // 解析出来的最外层数组 @property (nonatomic,strong) NSArray *provinceArr; // 省 @property (nonatomic,strong) NSArray *countryArr; // 市 @property (nonatomic,strong) NSArray *districtArr; // 区 @property (nonatomic,assign) NSInteger index1; // 省下标 @property (nonatomic,assign) NSInteger index2; // 市下标 @property (nonatomic,assign) NSInteger index3; // 区下标 @property (nonatomic,strong) ActionSheetCustomPicker *picker; // 选择器 @property (weak, nonatomic) IBOutlet UILabel *detailAddress; // 具体地址
我已经把Json的地址文件放到工程中了
本次演示Demo的github地址:Demo演示地址,需要的请戳
逻辑很简单,第一个界面进来是空的地址,点过去到第二个界面选择地址,第二个界面点击“出来吧小伙子”,弹出picker选择器,选择地址显示出来,回到第一个界面后地址是显示选择的地址,那么再点击地址进到第二个界面的时候,点出picker再次选择地址的时候,这个时候咱们需要让地址定位在上次选择地址的的那三个位子,也就是有值的情况下要一一对应,具体如下:
1.每次进来或者滚动PickerView的时候需要进行重新计算着三个数组,实时更新对应选择的数组
- (void)loadFirstData { // 注意JSON后缀的东西和Plist不同,Plist可以直接通过contentOfFile抓取,Json要先打成字符串,然后用工具转换 NSString *path = [[NSBundle mainBundle] pathForResource:@"address" ofType:@"json"]; NSLog(@"%@",path); NSString *jsonStr = [NSString stringWithContentsOfFile:path usedEncoding:nil error:nil]; self.addressArr = [jsonStr mj_JSONObject]; NSMutableArray *firstName = [[NSMutableArray alloc] init]; for (NSDictionary *dict in self.addressArr) { NSString *name = dict.allKeys.firstObject; [firstName addObject:name]; } // 第一层是省份 分解出整个省份数组 self.provinceArr = firstName; } // 根据传进来的下标数组计算对应的三个数组 - (void)calculateFirstData { // 拿出省的数组 [self loadFirstData]; NSMutableArray *cityNameArr = [[NSMutableArray alloc] init]; // 根据省的index1,默认是0,拿出对应省下面的市 for (NSDictionary *cityName in [self.addressArr[self.index1] allValues].firstObject) { NSString *name1 = cityName.allKeys.firstObject; [cityNameArr addObject:name1]; } // 组装对应省下面的市 self.countryArr = cityNameArr; // index1对应省的字典 市的数组 index2市的字典 对应县的数组 self.districtArr = [[self.addressArr[self.index1] allValues][0][self.index2] allValues][0]; }
2.点击按钮弹出Picker
- (IBAction)click:(id)sender { // NSArray *initialSelection = @[@(self.index1), @(self.index2),@(self.index3)]; // 点击的时候传三个index进去 self.picker = [[ActionSheetCustomPicker alloc]initWithTitle:@"选择地区" delegate:self showCancelButton:YES origin:self.view initialSelections:@[@(self.index1),@(self.index2),@(self.index3)]]; self.picker.tapDismissAction = TapActionSuccess; [self.picker showActionSheetPicker]; }
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { switch (component) { case 0: { self.index1 = row; self.index2 = 0; self.index3 = 0; // [self calculateData]; // 滚动的时候都要进行一次数组的刷新 [self calculateFirstData]; [pickerView reloadComponent:1]; [pickerView reloadComponent:2]; [pickerView selectRow:0 inComponent:1 animated:YES]; [pickerView selectRow:0 inComponent:2 animated:YES]; } break; case 1: { self.index2 = row; self.index3 = 0; // [self calculateData]; [self calculateFirstData]; [pickerView selectRow:0 inComponent:2 animated:YES]; [pickerView reloadComponent:2]; } break; case 2: self.index3 = row; break; default:break; } }
4.当选择完之后调用
// 点击done的时候回调 - (void)actionSheetPickerDidSucceed:(ActionSheetCustomPicker *)actionSheetPicker origin:(id)origin { NSMutableString *detailAddress = [[NSMutableString alloc] init]; if (self.index1 < self.provinceArr.count) { NSString *firstAddress = self.provinceArr[self.index1]; [detailAddress appendString:firstAddress]; } if (self.index2 < self.countryArr.count) { NSString *secondAddress = self.countryArr[self.index2]; [detailAddress appendString:secondAddress]; } if (self.index3 < self.districtArr.count) { NSString *thirfAddress = self.districtArr[self.index3]; [detailAddress appendString:thirfAddress]; } // 此界面显示 self.detailAddress.text = detailAddress; // 回调到上一个界面 self.myBlock(detailAddress,@[@(self.index1),@(self.index2),@(self.index3)]); }
感觉也没什么可以说的,大家需要的还是去github下载下来跑跑看吧,一个简单的demo
12.5日更新:很多人问我如何自定义上面的cancel和done按钮,都自己不找找API的,哎,还是写出来吧
// 可以自定义左边和右边的按钮 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; button.frame = CGRectMake(0, 0, 44, 44); [button setTitle:@"我擦" forState:UIControlStateNormal]; UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom]; [button1 setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; button1.frame = CGRectMake(0, 0, 44, 44); [button1 setTitle:@"呵呵" forState:UIControlStateNormal]; [self.picker setCancelButton:[[UIBarButtonItem alloc] initWithCustomView:button]]; [self.picker setDoneButton:[[UIBarButtonItem alloc] initWithCustomView:button1]]; [self.picker addCustomButtonWithTitle:@"再来一次" value:@(1)];
Demo地址:点我传送
Over~~~~~~~~~~~~~~~~~~~~~