iOS增强版的UIDatePicker,省 市 县三级联动地址选择器(ActionSheetCustomPicker)

版权声明:本文为博主原创文章,未经博主允许不得转载。转载请Email我....... https://blog.csdn.net/Deft_MKJing/article/details/51568392

一般的项目中都会有一个选择地址的需求,系统的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];
}


3.实现Picker的代理方法,下面只展示最关键的一个 当case = 0的时候,第一个index=row,其他两个为0,重新调用calculateData计算数组,然后刷新对应市和县的数组到picker上面,保持数据的一致性,当case = 1和2的时候,进行类似的操作

- (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~~~~~~~~~~~~~~~~~~~~~




展开阅读全文

没有更多推荐了,返回首页