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

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




  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
/** * 只显示份一级 * provinceBlock : 回调份 */ (instancetype)provincePickerViewWithProvinceBlock:(void(^)(NSString *province))provinceBlock; /** * 显示份和级 * cityBlock : 回调份和城 */ (instancetype)cityPickerViewWithCityBlock:(void(^)(NSString *province, NSString *city))cityBlock; /** * 显示份和级和区域 * areaBlock : 回调份城和区域 */ (instancetype)areaPickerViewWithAreaBlock:(void(^)(NSString *province, NSString *city, NSString *area))areaBlock; /** * 只显示份一级 * province : 传入了份自动滚动到份,没有传或者找不到默认选中第一个 * provinceBlock : 回调份 */ (instancetype)provincePickerViewWithProvince:(NSString *)province provinceBlock:(void(^)(NSString *province))provinceBlock; /** * 显示份和级 * province,city : 传入了份和城自动滚动到选中的,没有传或者找不到默认选中第一个 * cityBlock : 回调份和城 */ (instancetype)cityPickerViewWithProvince:(NSString *)province city:(NSString *)city cityBlock:(void(^)(NSString *province, NSString *city))cityBlock; /** * 显示份和级和区域 * province,city : 传入了份和城和区域自动滚动到选中的,没有传或者找不到默认选中第一个 * areaBlock : 回调份城和区域 */ (instancetype)areaPickerViewWithProvince:(NSString *)province city:(NSString *)city area:(NSString *)area areaBlock:(void(^)(NSString *province, NSString *city, NSString *area))areaBlock;
### 回答1: uniapp是一款跨平台的开发框架,可以让开发者使用Vue.js来开发iOS、Android、H5等多个平台的应用程序。要实现省市区三级联动功能,可以使用uniapp的picker选择器组件结合数据源来实现。 首先,需要准备好省市区的数据源。可以通过网络请求获取数据,也可以在本地定义一个JSON数据文件来存储省市区的信息。 然后,在页面中使用picker选择器组件来展示三级联动的效果。可以使用三个picker组件来分别展示、区的选项,用户通过滑动选择器中的选项来进行选择。 在数据绑定方面,可以通过在data中定义一个变量来存储用户的选择结果。比如,可以定义一个数组变量selected来存储用户选择的、区的信息。通过监听picker的change事件,在事件处理函数中更新selected数组的值。 最后,在页面中展示用户选择的结果。可以使用文本框等组件来展示、区的信息,将selected数组中的值显示出来。 通过上述步骤,就可以实现uniapp省市区三级联动的功能。用户可以通过滑动选择器来选择、区的选项,选择结果会实时更新并展示在页面上。 ### 回答2: uniapp是一款跨平台的开发框架,适用于开发微信小程序、App和H5页面。要实现省市区三级联动,可以采用uniapp的picker组件以及相关的数据处理方法。以下是实现的步骤: 1. 在页面的vue文件中,引入picker组件,并将其放置在需要选择省市区的位置。例如: ``` <template> <view> <picker :value="value" mode="multi-selector" @change="pickerChange"> <view class="picker">选择省市区</view> </picker> </view> </template> ``` 2. 在`data`中定义需要使用的数据,如省市区的数据源,以及选择结果的变量。例如: ``` data() { return { value: [], provinces: ['北京', '上海', '广东', ...], cities: { '北京': ['北京'], '上海': ['上海'], '广东': ['广州', '深圳', '珠海', ...], ... }, areas: { '北京': { '北京': ['东城区', '西城区', '朝阳区', ...], ... }, '上海': { '上海': ['黄浦区', '徐汇区', '长宁区', ...], ... }, ... } }; }, ``` 3. 在`methods`中定义选择器的change事件处理函数,用来更新选择结果的变量。例如: ``` methods: { pickerChange(e) { const value = e.detail.value; const province = this.provinces[value[0]]; const city = this.cities[province][value[1]]; const area = this.areas[province][city][value[2]]; this.value = value; console.log('选择结果:', province, city, area); // 可以在此处理选择结果,如发送请求获取相应的数据等 }, } ``` 以上就是使用uniapp实现省市区三级联动的基本步骤。利用picker组件和相应的数据处理方法,可以实现用户选择省市区的功能,并获取相应的选择结果,方便后续的数据处理和操作。 ### 回答3: Uniapp是一种基于Vue框架的跨平台开发工具,可以方便快捷地开发出同时适用于多个平台的应用程序。要实现省市区三级联动功能,可以通过以下步骤来完成。 首先,我们需要准备好省市区的数据。可以在后端提供接口获取到省市区的数据,然后将数据存储到前端的数据源中。 然后,在前端的页面中布局好三个级别的选择框,用于显示省市区的选择结果。 接着,需要为每个选择框绑定一个change事件,在选择框的change事件中根据选择的值,动态更新下一级选择框的选项。 具体的实现方式是,当选择框的值发生改变时,根据选择的份,在数据源中找到对应的的数据,并更新选择框的选项。当选择框的值发生改变时,根据选择的,再次在数据源中找到对应的区的数据,并更新区选择框的选项。 最后,当三个选择框的值都确定之后,就可以得到最终的选择结果,可以将结果保存到数据源中,或者作为参数传递给后端接口进行相应的操作。 总结起来,实现uniapp省市区三级联动的过程包括准备数据、布局页面、绑定change事件和更新选项。通过这样的实现,用户可以方便地选择省市区信息,并进行相应的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值