UIPickerView的二级联动

开发中会遇到让用户选择城市的需求,这就需要用到UIPickerView的二级联动,实现起来虽然比较简单,但却需要好好思考清楚才能更好的理解代码.

1.搭建界面如下:

UIPickerView的二级联动_第1张图片

2.将textFeild连线至控制器类扩展中,设置控制器为textFeild的代理.
3.创建模型文件,并设置内容如下:

模型.h文件
#import 

@interface DLProvinces : NSObject

@property(nonatomic,strong) NSArray *cities;
@property(nonatomic,strong) NSString *name;

+ (instancetype)provincesWithDict:(NSDictionary *)dict;

@end

模型.m文件

#import "DLProvinces.h"

@implementation DLProvinces

+ (instancetype)provincesWithDict:(NSDictionary *)dict{
    DLProvinces *p = [[self alloc] init];
    [p setValuesForKeysWithDictionary:dict];
    return p;
}
@end

4.在控制器中创建数组来接收模型数据.

@property(nonatomic,strong) NSMutableArray *province;

//数组懒加载
- (NSMutableArray *)province{
    
    if (_province == nil) {
        _province = [NSMutableArray array];
        NSString *path = [[NSBundle mainBundle] pathForResource:@"provinces.plist" ofType:nil];
        NSArray *arr = [NSArray arrayWithContentsOfFile:path];
        for (NSDictionary *dict in arr) {
            DLProvinces *p = [DLProvinces provincesWithDict:dict];
            [_province addObject:p];
        }
    }
    return _province;
}

5.创建UIPickerView,设置textFeild的inputView为cityPicker,并创建一个成员变量cityPicker存储cityPicker.

//成员变量cityPicker
@property(nonatomic,strong) UIPickerView *cityPicker;

- (void)viewDidLoad {
    [super viewDidLoad];
    //设置加载界面后cityField获取焦点
    [_cityField becomeFirstResponder];
    //创建城市键盘
    [self setCityField];
 }
//自定义城市键盘
- (void)setCityField{
    UIPickerView *cityPicker = [[UIPickerView alloc] init];
    //设置cityPicker的数据源与代理为当前控制器
    cityPicker.dataSource = self;
    cityPicker.delegate = self;
    _cityPicker = cityPicker;
    _cityField.inputView = cityPicker;

6.实现数据源与代理方法

注意:定义一个成员变量,记录选中了第0列的哪一行.解决两列同时滚动脚标越界的问题.
@property(nonatomic,assign) NSInteger proIndex;

#pragma mark - UIPickerViewDataSource
//返回列数
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    
    return 2;
}
//返回行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
   //判断当前是第几列
    if (component == 0) {
        return self.province.count;
    }else{
        //取出选中的省会
        DLProvinces *p = self.province[_proIndex];
        return  p.cities.count;
    }
}
//返回第component列第row行的文字
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
    //判断当前是第几列
    if (component == 0) {
        DLProvinces *p = self.province[row];
        return  p.name;
    }else{
        //取出选中的省会
        DLProvinces *p = self.province[_proIndex];
        return p.cities[row];
    }
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    
    if (component == 0) {
        //记录当前选中的省会
        _proIndex = [pickerView selectedRowInComponent:0];
        [pickerView reloadComponent:1];
    }
    //获取选中的省会
    DLProvinces *p = self.province[_proIndex];
    //获取选中的城市
    NSInteger cityIndex = [pickerView selectedRowInComponent:1];
    NSString *cityName = p.cities[cityIndex];
    _cityField.text = [NSString stringWithFormat:@"%@ %@",p.name,cityName];
}

7.设置cityField不能输入文字,加载时显示第0列第0行的数据.

#pragma mark - UITextFieldDelegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    return NO;
}

//文本框获取焦点时调用
- (void)textFieldDidBeginEditing:(UITextField *)textField;{

    [self pickerView:_cityPicker didSelectRow:0 inComponent:0];
}

效果图:

UIPickerView的二级联动_第2张图片

你可能感兴趣的:(UIPickerView的二级联动)