您的位置:首页 > 移动开发 > IOS开发

IOS级联(省份和城市)

2016-01-16 17:19 501 查看


IOS省份和城市的级联


1.资料准备

一个plist文件,plist文件的根目录是一个省份的字段name和一个存放城市名称的数组,如下图所示




界面的效果如下:一个label和一个TextField即可





2.创建一个模型类ProvinceModel

模型类的声明代码如下

//声明一个name保存省份的名称
@property (nonatomic, strong) NSString *name;
//声明一个citys数组保存所有的城市
@property (nonatomic, strong) NSArray *citys;

//声明构造方法和类工厂方法
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)modelWithDict:(NSDictionary *)dict;


模型类的实现代码如下

//实现构造函数
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
self.name = dict[@"name"];
self.citys = dict[@"cities"];
}
return self;
}

//实现类工厂方法
+ (instancetype)modelWithDict:(NSDictionary *)dict
{
ProvinceModel *myModel = [[ProvinceModel alloc]initWithDict:dict];
return myModel;
}


3.声明一个ProvinceField类,继承自UITextField


3.1在.m文件中定义一个数组(myArray)保存plist文件的所有字典,然后用懒加载方法加载字典数据到这个数组中,实现代码如下:

//声明数组保存字典
@property (nonatomic, strong) NSArray *myArray;

//懒加载字典
-(NSArray *)myArray{
if (_myArray == nil) {
NSMutableArray *arrayM = [NSMutableArray array];
NSString *path = [[NSBundle mainBundle]pathForResource:@"provinces.plist" ofType:nil];
NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
for (NSDictionary *dict in arrayDict) {
ProvinceModel *myModel = [ProvinceModel modelWithDict:dict];
[arrayM addObject:myModel];
}
_myArray = arrayM;
}
return _myArray;
}
//执行到这里数组_myArray就保存了plist文件的所有字典数据


设置当键盘加载出来的时候显示我们自定义的UIPickerView,因为在自定义的UIPickerView中加载我们的数据,因此需要遵循UIPickerViewDelegate代理协议和UIPickerViewDataSource数据源协议,代码如下:

@interface ProvinceField () <UIPickerViewDelegate,UIPickerViewDataSource>


遵循协议和代理后我们要设置自定义UIPickerView的协议和代理,我们自定义一个函数setup,在函数定义一个UIPickerView,然后设置它的代理,代码如下

//初始化的时候加载自定义的pickView
- (void)setup{
UIPickerView *myPick = [[UIPickerView alloc]init];
//设置代理
myPick.delegate = self;
//设置数据源
myPick.dataSource = self;
//设置加载时候的pickView
self.inputView = myPick;
}


为了在main.storyboard中的UITextField加载出来的时候它的键盘类型为我们的自定义UIPickerView,我们需要重写awakeFromNib方法和initWithFrame:方法,代码如下

- (void)awakeFromNib{
[self setup];
}

- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
[self setup];
}
return self;
}


3.2去到Main.storyboard修改UITextField的class为我们创建的ProvinceField类,如下图所示






接下来是实现我们的UIPickerViewDelegate代理方法设置数据,先设置列数为2,第0列显示省份名,第1列显示城市名

//设置列数,第0列显示省份名,第1列显示城市名
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 2;
}


从plist文件分析,第0列的行数为前面声明的@property (nonatomic, strong) NSArray myArray数组的个数,第1列的城市名的行数要根据第0列的省名称来决定,因此我们要定义一个数,记录当前第0列当前选择的下标,然后通过下标找到该省份名,最后通过省份名找到城市的个数.综合分析后,我们需要在- (void)pickerView:(UIPickerView)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component {}这个方法中设置当前选择的第1列的某行,保存起来,代码如下:

//保存当前省份的下标
@property (nonatomic, assign) NSInteger provinceIndex;

//记录省份的坐标
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
//如果选择的是第0行,保存该下标
if (component == 0) {
self.provinceIndex = row;
//刷新数据
[pickerView reloadAllComponents];
//设置第1列也选择第一行
[pickerView selectRow:0 inComponent:1 animated:YES];
}
}


接下来设置2列的行数,代码为

//设置行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
//第0列
if (component == 0) {
return self.myArray.count;
}
//第一列
else{
//根据省份才能找到城市的count
ProvinceModel *myModel = self.myArray[self.provinceIndex];
return myModel.citys.count;

}
}


接着是设置数据,代码如下:

//返回数据
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
//设置第一行的数据
if (component == 0) {
ProvinceModel *myModel = self.myArray[row];
return myModel.name;
}
//设置第二行的数据(要根据省份拿到对应的cities)
else{
ProvinceModel *myModel = self.myArray[self.provinceIndex];
return myModel.citys[row];
}
}


为了在选择的时候将省份和城市显示到UITextField上,我们需要在- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 这个代理方法做一些处理,代码为:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
//如果选择的是第0行,保存该下标
if (component == 0) {
self.provinceIndex = row;
//刷新数据
[pickerView reloadAllComponents];
//设置第1列也选择第一行
[pickerView selectRow:0 inComponent:1 animated:YES];
}

//将选中得数据显示到text中
//获取第0列选中得省份
NSString *province;
ProvinceModel *myModel = self.myArray[self.provinceIndex];
province = myModel.name;

//获取城市
NSString *city;
//获取第1列的城市的行数
NSInteger selectrow = [pickerView selectedRowInComponent:1];
city = myModel.citys[selectrow];
NSString *showText = [NSString stringWithFormat:@"%@-%@",province,city];
self.text = showText;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: