UIPickerView的二级联动

作者: letaibai | 来源:发表于2016-04-21 18:16 被阅读4155次

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

1.搭建界面如下:

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

模型.h文件
#import <Foundation/Foundation.h>

@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];
}

效果图:

相关文章

网友评论

  • 龙_8252:请问一下,这玩意歪的有办法弄成直的不,就是选中行上下
  • 梁森的简书:有demo吗
  • Mr丶Wayne:可不可以给一份demo或者plist文件
    Mr丶Wayne:waynehao521@163.com
  • 7a30c92646be:省份的plist文件可以给一下吗 1650880533@qq.com
  • 小嘴冰凉别乱亲:写的挺详细, 省份的plist 文件表 发我一份吧,谢谢哈, 发到我的邮箱 568825464@qq.com 感谢
  • 昊楷:省份的plist 文件可以给一份吗
    56f5f77144ad:@letaibai 365407585@qq.com,我的邮箱,想要一份plist文件,谢谢
    昊楷:@letaibai 78142132@qq.com 谢谢
    letaibai:@昊楷 留个邮箱给你发过去

本文标题:UIPickerView的二级联动

本文链接:https://www.haomeiwen.com/subject/euitrttx.html