实现城市选择,选中省时,后来自动显示相对应的城市,并且下面会打印出来对应的省和城市

.

因为plist里面是一个一个的字典.

1.字典转模型

HMCities.h

#import <Foundation/Foundation.h>
@interface HMCities : NSObject
@property(nonatomic, strong)NSArray *cities;
@property(nonatomic, copy)NSString *name;
-(instancetype)initWithDict:(NSDictionary *)dict;
+(instancetype)citiesWithDict:(NSDictionary *)dict;
@end

HMCities.m

#import "HMCities.h"
@implementation HMCities
-(instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+(instancetype)citiesWithDict:(NSDictionary *)dict
{
return [[self alloc]initWithDict:dict];
}
@end

第二步:懒加载数据

#import "ViewController.h"
#import "HMCities.h"
@interface ViewController ()
@property(nonatomic, strong)NSArray *cities;
@end
@implementation ViewController
#pragma mark /*******************懒加载数据******************/
-(NSArray *)cities
{
if (_cities == nil) {
NSString *path = [[NSBundle mainBundle]pathForResource:@"cities.plist" ofType:nil];
NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
NSMutableArray *arrayM = [NSMutableArray array];
for (NSDictionary *dict in arrayDict) {
HMCities *cities = [HMCities citiesWithDict:dict];
[arrayM addObject:cities];
}
_cities = arrayM;
}
return _cities;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@",self.cities);
}
@end

3.搭建界面  上面是pickerView. 下面有两个tableView.  设置控件的约束

4.  设置pickerView的数据源和代理统一为View Controller,实现数据源方法和代理方法.

#pragma mark /******************UIPickerView的数据源方法****************/
//返回有多少列
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return ;
}
//返回每列有多少行,因为有两列数据,而且第1列有多少行,是根据第0列被选中那一行决定的.所以需要先进行判断
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == ) {//表示第0列被选中,(省份被选中)
//返回第0列有多少行
return self.cities.count;
}else{//表示第1列被选中,(城市)
//先要使用selectedRowInComponent方法获取第0列的那一行被选中,
NSInteger idx_row = [self.pickerView selectedRowInComponent:];
//获取第0列被选中行的模型
HMCities *model = self.cities[idx_row];
//返回第1列有多少行
return model.cities.count;
}
}

5.实现功能

1.当省份发生改变时,城市对应的发生改变.

2.省份发生改变,城市对应发生改变时,显示第一个城市.

#pragma mark /*******************UIPickerView代理方法******************/
//返回每一行的数据
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == ) { //表示索引为1的列被选中--要的是城市的名称
HMCities *model = self.cities[row];//获取数据模型
return model.name; //返回对应行要显示的数据
} else //表示索引为1的列被选中,要的是城市的名称
{ //获取第0列哪一行被选中(那个省份被选中)
NSInteger idx_row = [self.pickerView selectedRowInComponent:];
//获取当前第0列选中的省份模型
HMCities *model = self.cities[idx_row];
return model.cities[row];
}
}
//选中行改变事件,改变第0列数据时,第1列要相对应的显示不同的数据(第0列选择省份,第1列显示对应的城市)
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == ) {//表示第0列发生了改变,用户重新选择了第0列的数据(省份发生变化)
//刷新索引为1列中的数据,只有第1列发生变化,只刷新第1列的数据就可以.
[pickerView reloadComponent:]; //刷新所有数据
//[pickerView reloadAllComponents]; //设置当第0列发生改变时,第1列显示第0行的数据(省份发生变化时,显示第一个城市名称)
//设置索引为1的列的第0行被选中
[pickerView selectRow: inComponent: animated:YES];
} }

6.实现功能

1.选中省份和城市时,把数据显示到对象的label上

1.1创建省份和城市的属性

//省份
@property (weak, nonatomic) IBOutlet UILabel *provinceLabel;
//城市
@property (weak, nonatomic) IBOutlet UILabel *cityLabel;

把方法实现到didSelectRow方法里面

//获取当前选中行的数据,并且将选中行的数据显示到对应的label上
//获取选中的省份
NSInteger idx_province = [pickerView selectedRowInComponent:];
HMCities *model = self.cities[idx_province];
self.provinceLabel.text = model.name; //选中城市
//获取第1列被选中那一行
NSInteger idx_city = [pickerView selectedRowInComponent:];
self.cityLabel.text = model.cities[idx_city];

让程序一开始运行,label就显示数据.

方法实现到viewDidLoad方法里面

- (void)viewDidLoad {
[super viewDidLoad];
//NSLog(@"%@",self.cities);
//手动设置选中那一行
[self.pickerView selectRow: inComponent: animated:YES];
[self.pickerView selectRow: inComponent: animated:YES]; //手动调用didSelectRow方法,让程序一开始运行,label就显示数据.
[self pickerView :self.pickerView didSelectRow: inComponent:];
[self pickerView :self.pickerView didSelectRow: inComponent:]; }

功能全部实现完成,最后的Bug.当省份一列正在运行时,在运行城市一列程序就会崩溃.

1.产生Bug的原因

. 通过设置全局断点找到错误。
. 先看几个知识点:

titleForRow方法什么时候执行:在滚动的过程当中会一直被执行

didSelectRow方法什么时候执行:当滚动完毕, 已经确定哪行被选中后, 会调用didSelectRow方法。在一直滚动的过程当中, didSelectRow方法时不会被调用的。

numberOfRowsInComponent方法什么时候执行:因为在didSelectRow方法中调用了[pickerView reloadComponent:];方法来刷新数据。而刷新数据的含义就是重新调用数据源方法和代理方法,所以numberOfRowsInComponent也会被调用

[self.pickerView selectedRowInComponent:];这个方法返回的是, 给定的列中当前选中的行的索引。(注意: 在picker view滚动的过程当中(滚动还没有停止, 还没有触发DidSelectRow方法),此时selectedRowInComponent方法, 返回的就是当前行中所显示的哪行的索引。

当省份在运行时,还没有确定被选中的具体省份.这个时候运行城市列表.  城市一列会发生改变, 城市列不能和省份列相对应. 这样会造成数据越界.

同理(当运行城市列表时,运行省份列表也会发生程序崩溃).

解决:创建一个记录当前选中省份的索引,城市列通过索引获取当前城市列的行,当省份列在运行时,城市列不受干扰,只有在省份列停止时,调用didSelectRow方法,才会改变新的索引.

创建记录当前选中省份的索引属性

//用来记录当前选中省份的索引
@property(nonatomic, assign) NSInteger idx_row;

在numberOfRowsInComponent方法中,把选中省份的索引记录下来

//先要使用selectedRowInComponent方法获取第0列的那一行被选中,
NSInteger idx_row = [self.pickerView selectedRowInComponent:]; //将当前选中的省份的索引记录下来
self.idx_row = idx_row;

在titleForRow方法中,返回每一行数据时,通过过记录的索引获取当前第0列选中的省份模型

 //获取当前第0列选中的省份模型
HMCities *model = self.cities[self.idx_row];
return model.cities[row];

在didSelectRow方法中,设置table数据时,使用记录的索引设置要显示的省份.

//获取当前选中行的数据,并且将选中行的数据显示到对应的label上
//获取选中的省份
//NSInteger idx_province = [pickerView selectedRowInComponent:0];
NSInteger idx_province = self.idx_row;
HMCities *model = self.cities[idx_province];
self.provinceLabel.text = model.name;

UIPIckerView现实城市选择的更多相关文章

  1. 移动端城市选择JavaScript插件(基于WG的城市选择插件的修改版本)

    周末的时候趁着一次机会,拿WG(博客)开发的城市选择插件改了一个移动端可以直接用的城市选择插件. 原版插件是基于原声JavaScript写的,在此先感谢作者. 我做的只是依照肯德基注册会员的页面的交互 ...

  2. Android之自定义控件-城市选择

    实现效果: 图片素材:           --> 首先, 城市数据字节放在 Json 文件, 就不网络获取了. city.json 存放 Json 数据: { "result&quo ...

  3. 仿51job.com城市选择框特效

    650) this.width=650;" border="0" alt="" src="http://img1.51cto.com/att ...

  4. 纯原生js移动端城市选择插件

    接着上一篇纯js移动端日期选择插件,话说今天同事又来咨询省市县联动的效果在移动端中如何实现,还是老样子,百度上一搜,诶~又全是基于jquery.zepto的,更加可恨的是大多数都是PC版的,三个sel ...

  5. 基于jquery的城市选择插件

    城市选择插件的难度不是很大,主要是对dom节点的操作.而我写的这个插件相对功能比较简答,没有加入省市联动. 上代码好了,参照代码的注释应该比较好理解. /* *基于jquery的城市选择插件 *aut ...

  6. android wheelview实现三级城市选择

    很早之前看淘宝就有了ios那种的城市选择控件,当时也看到网友有分享,不过那个写的很烂,后来(大概是去年吧),我们公司有这么一个项目,当时用的还是网上比较流行的那个黑框的那个,感觉特别的丑,然后我在那个 ...

  7. ionic-基于angularjs实现的多级城市选择组件

    大家都知道在移动端的选择地区组件,大部分都是模拟IOS选择器做的城市三级联动,但是在IOS上比较好,在Android上因为有的不支持ion-scroll.所以就会出现滚动不会自动回滚到某一个的正中间. ...

  8. mpvue微信小程序多列选择器用法:实现省份城市选择

    前言 微信小程序默认给我们提供了一个省市区的picker选择器,只需将mode设置为region即可 <picker mode="region" bindchange=&qu ...

  9. 【React】开发一个城市选择控件

    想到做这个,是因为无意中在github上看到了这一个仓库https://github.com/lunlunshiwo/ChooseCity,做的就是一个城市选择控件,是用vue写的,说的是阿里的一道题 ...

随机推荐

  1. 一首诗,致亲爱的csdn

    来自csdn的Rachel-Zhang姐姐 还记得--致亲爱的csdn 还记得你年轻时的摸样? 简单的文字,无瑕的脸庞. 现在的你,满脸风霜. 五粮液的广告,在我的文章中久久荡漾. 还记得当初的梦想? ...

  2. jQuery学习笔记(二)jQuery中DOM操作

    目录 DOM操作分类 jQuery中的各种DOM操作 查找节点 创建节点 删除节点 复制节点 替换节点 包裹节点 属性操作 样式操作 对HTML.文本和值的操作 遍历节点 CSS-DOM操作 小结 本 ...

  3. winform常用的属性(listview),常用容器(二者结合)

    ListVies控件主要用于展示数据(非常实用和重要的控件) FullRowSelect:设置是否行选择模式.(默认为false) (开启之后一下选中一行数据) ___________________ ...

  4. HDU 1272 小希的迷宫 并查集

    小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  5. webpack详细配置讲解

    //常见的Webpack配置文件var webpack = require('webpack');var HtmlWebpackPlugin = require('html-webpack-plugi ...

  6. 在myeclipse下安装svn的几种方式

    方法一:在线安装 1.打开HELP->MyEclipse Configuration Center.切换到SoftWare标签页. 2.点击Add Site 打开对话框,在对话框Name输入Sv ...

  7. jQuery3的新特性

    前言:自从react,vue等方便的新框架出现后,好多大公司已经摒弃了jquery,但是大部分的公司还在使用,并且jquery的版本还在一直更新中.jquery2.x版本将不再支持IE6/7/8浏览器 ...

  8. Hook机制里登场的角色

    稍有接触过 WordPress 主题或插件制作修改的朋友,对 WordPress 的Hook机制应该不陌生,但通常刚接触WordPress Hook 的新手,对其运作原理可能会有点混乱或模糊.本文针对 ...

  9. 为什么JAVA的垃圾回收机制无法避免内存泄漏

    一.本文参考:    1.<深入理解java虚拟机 JVM高级特性与最佳实践>    2.http://coderevisited.com/memory-leaks-in-java/   ...

  10. TCP/IP协议学习(六) 链路层详解

    学习知识很简单,但坚持不懈却又是如此的困难,即使一直对自己说"努力,不能停下"的我也慢慢懈怠了... 闲话不多说,本篇将讲述TCP/IP协议栈的链路层.在本系列第一篇我讲到,TCP ...