iOS开发——高级UI之OC篇&UIdatePicker&UIPickerView简单使用

UIdatePicker&UIPickerView简单使用

/***********************************************************************************/

一:UIdatePicker:(日期控件)

1.UIDatePicker什么时候用? 当用户选择日期的时候,一般弹出一个UIDatePicker给用户选择。

2.UIDatePickerios6和ios7/8的区别

下面看看使用封装的代码怎么去实现它:

因为这个比较简单,所以这里只是简单给出了封装之后UIDatePicker的实现代码

由于我们平时一般都是使用它用来输入一些日期到我们想要的地方,特别是文本框,所以如果我们要封装也是在文本框里面封装,因为文本框邮一个属性inputView,我只要在里面将我们的UIDatePicker设置为这个属性就可以。

 1 -(void)awakeFromNib
 2
 3 {
 4
 5     [self initWithBirthView];
 6
 7 }
 8
 9
10
11 -(instancetype)initWithFrame:(CGRect)frame
12
13 {
14
15     if (self == [super initWithFrame:frame]) {
16
17         [self initWithBirthView];
18
19     }
20
21     return self;
22
23 }
24
25
26
27 -(void)initWithBirthView
28
29 {
30
31     UIDatePicker *date = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
32
33     date.locale = [NSLocale localeWithLocaleIdentifier:@"zh"];
34
35     date.datePickerMode = UIDatePickerModeDate;
36
37
38
39     [date addTarget:self action:@selector(changeData:) forControlEvents:UIControlEventValueChanged];
40
41
42
43
44
45     self.inputView = date;
46
47 }
48
49
50
51 -(void)changeData:(UIDatePicker *)datePicker
52
53 {
54
55     NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
56
57     fmt.dateFormat = @"yyyy-MM-dd";
58
59     NSString *data = [fmt stringFromDate:datePicker.date];
60
61
62
63     self.text = data;
64
65
66
67 }
68
69
70
71   

当我们滚动下面的转盘是文本框也会动态的现实对应的时间:

/********************************************************************************************/

二:UIPickerView:(轮转控件)

这里先说一下UIPickerView相对UIDatePicker要难一点,他的使用类似tableView,但是如果你只是要简单的实现那就没你想的那么难的,不过这个在实际开发中一般很少用到,就算真的用到了我们一一般也是使用已经封装好的直接拿来用。

1.UIPickView什么时候用?
• 通常在注册模块,当用户需要选择一些东西的时候,比如说城市,往往

弹出一个PickerView给他们选择。

2.UIPickView常见用法,演示实例程序 1>独立的,没有任何关系 =>菜单系统。 2>相关联的,下一列和第一列有联系=>省会城市选择 3>图文并帽,=>国旗选择。

3.UIPickView

搭建界面
1> 注意点:PickerView的高度不能改,默认162,PickerView里面每行的高度 可以改,不要弄混淆了。

2.pickerView显示数据

  • 1> 如何使用PickerView展示数据? 进入PickerView头文件,有数据源和代理,联想到UITableView,模仿 UITableView的用法。
  • 2> 让控制器作为PickerView的数据源,控制器遵守PickerView的数据源方法

2.1>两种方式:1.拖线 2.代码 2.2>系统自带的控件,数据源和代理属性不需要IBOutlet,也能拖 线。自己的属性,想要拖线,必须写IBOutlet。

3> PickerView的数据源方法

  • 1> numberOfComponentsInPickerView: 返回多少列
  • 2> pickerView:numberOfRowsInComponent: 返回第component列有多少 行
  • 3> 和UITableView的区别,每一行长什么样,是由PickerView的代理决 定的。
  • 4> 注意:如果没有返回每一行长什么样子,每行就会显示?,看见?,就 知道没有实现每一行长什么样子的方法。

4> PickerView的代理方法
1> 返回第component列第row行长什么样。

  • 第component列第row行的展示标题

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

  • 第component列第row行带属性的标题

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger) component

  • 第component列第row行展示的视图

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;

2> 返回第component列每一行的高度和宽度

  • - (CGFloat)pickerView:(UIPickerView *)pickerView
  • - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;

2> 返回第component列每一行的高度和宽度

  • - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component;
  • - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component;

3> 选中第component列第row行调用

  • - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component;

3. 加载plist数据

  • 1> 分析数据结构
  • 1> 大数组元素个数:多少列 2>大数组里面的小数组: 这一列有多少行。 3> 小数组里的字符串: 每行展示的样子

4.处理菜单选中业务

  • 1> 选中某一列某一行,显示出来
  • 2> 拖动不同列,改变不同的label,拖动第一列改变水果。
  • 3> 判断拖动哪一列,改变对应的label
  • 4> 在viewDidLoad中初始化label显示
  • 5> 取出数组中的数据给label直接赋值 _fruitLabel.text = self.foots[0][0]; 这种 方式不好,如果以后数组里有很多数据,要写很多行。
  • 6> 还有另外一种方式,通过调用代理,给label赋值.唯一不同的,就是列 数,搞个for循序就好了。

5.随机选中某一列的某一行

1> 如何选中某一行 [self.pickerView selectRow:row inComponent:component

animated:YES];
2> 先随机选中第0列的某一行,随机数取值范围看第0列总共有多少行,

arc4random_uniform(x)随机0~x-1的数
3> 避免随机出来的行数都一样,需要判断下,随机出来的行数和当前选中 的是否一样,一样就重新随机,用while判断,直到随机到不一样,才行。 3> 问题:label没有显示最新选中的一行。

原因:手动调用pickview滚动,选中某一行,不会触发代理,我们自己 主动调用代理,让lebel显示选中哪一行.

注意:只有用户手动滚动才可以触发pickview的代理方法。 4> 每一列都要随机选中,弄个for循序,遍历每一列都随机选中

下面就以代码的方式封装实现一下他:

关于UIPickView,我们知道他使用最多的地方就是在关于区域的选择,比如我们平时在使用一个App或者想要做某些是的时候,上面都需要我们滚动他来告诉他们对应的地址。

所以今天我吗就一地址的实现来封装一个UIPickView,关于其他一些只要会了这个基本上就没有任何问题了,因为这里涉及到了多列动态的现实数据。

首先我们来看看我们需要的plist数据,这里只有部分天朝区域

既然是程序员我们必定要想到MVC,所以根据plist文件创建模型,创建对应的属性,并且模型方法,将字典转成模型:

 1 #import <Foundation/Foundation.h>
 2
 3
 4
 5 @interface AddressModel : NSObject
 6
 7
 8
 9 @property (nonatomic, copy) NSString *name;
10
11
12
13 @property (nonatomic, copy) NSArray *cities;
14
15
16
17
18
19 +(instancetype)addWithDict:(NSDictionary *)dict;
20
21
22
23 @end

由于plsit比较简单,所以这里直接使用KVC,关于plist和字典转模型,请查看:。。。。。。,这里非常详细的介绍

 1 #import "AddressModel.h"
 2
 3
 4
 5 @implementation AddressModel
 6
 7
 8
 9 +(instancetype)addWithDict:(NSDictionary *)dict
10
11 {
12
13     AddressModel *model = [[self alloc] init];
14
15
16
17     [model setValuesForKeysWithDictionary:dict];
18
19
20
21     return model;
22
23 }
24
25
26
27 @end

然后同上,由于我们需要实现的事讲选中的内容输入到对应的文本框上面显示,所以先自定义一个继承自UItextFiled得类:

1 #import <UIKit/UIKit.h>
2
3
4
5 @interface AddressView : UITextField
6
7
8
9 @end

然后在里面创建我们需要的:注意这里最关键的是最后一行代码,没有这里一切都是扯蛋

 1 -(void)initWithAddressView
 2
 3 {
 4
 5     UIPickerView *pick = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
 6
 7     self.pick = pick;
 8
 9
10
11     pick.delegate = self;
12
13     pick.dataSource = self;
14
15
16
17     self.inputView = pick;
18
19 }

因为我们是要直接使用这个类,但是由于项目的需要,我们可能是使用StoryBoard创建也可能是使用纯代码创建所以,我们需要在两个方法中调用这个初始化的方法:

//纯代码创建

 1 -(instancetype)initWithFrame:(CGRect)frame
 2
 3 {
 4
 5     if (self == [super initWithFrame:frame]) {
 6
 7         [self initWithAddressView];
 8
 9     }
10
11     return self;
12
13 }
14
15 //从文件(Xib/StoryBoard创建)
16
17 -(void)awakeFromNib
18
19 {
20
21     [self initWithAddressView];
22
23 }
24
25  

关于懒加载就不多说了,说太多我也累,直接上代码:

 1 @property (nonatomic, strong) NSArray *cityArr;
 2
 3 -(NSArray *)cityArr
 4
 5 {
 6
 7     if (_cityArr == nil) {
 8
 9         NSArray *arr = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cities.plist" ofType:nil]];
10
11
12
13         NSMutableArray *cityArr = [NSMutableArray array];
14
15
16
17         for (NSDictionary *dict in arr) {
18
19             AddressModel *model = [AddressModel addWithDict:dict];
20
21
22
23             [cityArr addObject:model];
24
25         }
26
27
28
29         _cityArr = cityArr;
30
31     }
32
33     return _cityArr;
34
35 }

后面就是关键了,同时也是使用这个控件的一个难点:

遵守协议:

<UIPickerViewDataSource, UIPickerViewDelegate>

由于我们每选中第一列之后都要根据第一列中根据对应的选中项去处里面对应的子项(也就是城市),所以这里需要定义一个变量来记录一下我们选中的第一列:

@property (nonatomic, assign) NSInteger selectCom;

实现必须实现的代理方法:

/******************************************************************************

*                                                                            *

*                           UIPickerView代理方法                              *

*                                                                            *

*                            iCocos--Description                             *

*                                                                            *

******************************************************************************/

//列数

1 -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
2
3 {
4
5     return 2;
6
7 }

//对应列的行数

 1 -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
 2
 3 {
 4
 5     //如果是第0列
 6
 7     if (component == 0) {
 8
 9         //直接返回懒加载数组元素的个数
10
11         return self.cityArr.count;
12
13     } else {
14
15         //否则就是第一列了(因为这里只有两列)
16
17         //根据选中的第一列从数组中取出来,放到一个模型里面
18
19         AddressModel *model = self.cityArr[_selectCom];
20
21         //再根据这个模型里面的子项cities里面的元素个数返回对应的行数
22
23         return model.cities.count;
24
25     }
26
27 }

每列显示的标题文字

 1 -(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
 2
 3 {
 4
 5     //如果是第0列
 6
 7     if (component == 0) {
 8
 9         //直接返回懒加载数组元素中对应为name的值
10
11         return [self.cityArr[row] name];
12
13     } else {
14
15         //根据选中的第一列从数组中取出来,放到一个模型里面
16
17         AddressModel *model = self.cityArr[_selectCom];
18
19         //再根据这个模型里面的子项cities,取出里面的每一行返回来显示在第二列中
20
21         return model.cities[row];
22
23     }
24
25 }

根据选中显示对应的数据;

 1 -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
 2
 3 {
 4
 5     //如果是第0列
 6
 7     if (component == 0) {
 8
 9         //记录选中第0列的项
10
11         self.selectCom = [pickerView selectedRowInComponent:1];
12
13
14
15         //刷新数据(类似tableView的reLoadData)
16
17         [pickerView reloadComponent:1];
18
19
20
21         //默认选中项
22
23         [pickerView selectRow:0 inComponent:1 animated:YES];
24
25     } else {
26
27         //根据选中的第一列从数组中取出来,放到一个模型里面
28
29         AddressModel *model = self.cityArr[_selectCom];
30
31         //将选中的第一列使用一个变量再次纪录一下
32
33         NSInteger sel = [pickerView selectedRowInComponent:1];
34
35         //根据选中的第一列从cities里面取出对应子元素的所有元素,保存到一个字符串
36
37         NSString *name = model.cities[sel];
38
39         //根据UIPickerView上面对应列,对应行的数据动态的刷新并且显示到文本框中
40
41         self.text = [NSString stringWithFormat:@"%@ %@", model.name, name];
42
43     }
44
45 }

如下图:

当我们滚动最后选中左边一行之后右边会根据左边的现实做相应的改变,当我们在滚动最后选中右边列的任意项的时候,文本框根据两个现实的项取得对应的文字显示在界面上:

那么以后如果我需要使用这个或者是类似的,只需要把我们封装好的导入到项目中,然后将我们对应的textField的类设置为我们这里的类酒可以实现了,只需哟做少量的修改!

时间: 2024-10-23 09:42:18

iOS开发——高级UI之OC篇&UIdatePicker&UIPickerView简单使用的相关文章

iOS开发——高级技术精选OC篇&amp;Runtime之字典转模型实战

Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://www.cnblogs.com/iCocos/p/4676679.html http://www.cnblogs.com/iCocos/p/4725527.html 关于runtime的详细介绍及其相关的小实例 好了,这里就不多废话了,直接开干! 先来看看怎么使用Runtime给模型类赋值 iOS开发

iOS开发——完整项目实战OC篇&amp;百思不得姐第四天

iOS开发——完整项目实战OC篇&百思不得姐第四天 上午 一:自定义按钮使用九宫格布局 二:控件不能点击 三:获取用户点击了那个按钮 四:调整按钮内部控件的位置:主流->上下 五:不能直接使用self.navigationController中或者View中获取导航控制器 方法一: 方法二: 六:布局取整 1 // 总行数 2 3 // NSUInteger rows = sqaures.count / maxCols; 4 5 // if (sqaures.count % maxCols)

iOS开发——高级UI—OC篇&amp;退出键盘

退出键盘 iOS开发中键盘的退出方法用很多中我们应该在合适的地方使用合适的方法才能更好的提高开发的效率和应用的性能 下面给大家介绍几种最常用的键盘退出方法,基本上iOS开发中的键盘退出方法都是这几种中的一种活着几种. 一:textView 1 //通过委托来实现放弃第一响应者 2 #pragma mark - UITextView Delegate Method 3 -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(N

iOS开发——高级UI&amp;带你玩转UITableView

带你玩装UITableView 在实际iOS开发中UITableView是使用最多,也是最重要的一个控件,如果你不会用它,那别说什么大神了,菜鸟都不如. 其实关于UItableView事非常简单的,实际开发中用起来却没有那么简单就是因为他结合MVC使用,涉及到了模型数据的读取,自定义View,功能的拓展和更好的解藕,下面就带你玩一遍: UITableView的两种样式 UITableViewStylePlain UITableViewStyleGroupeds accessoryType UIT

iOS开发——网络使用技术OC篇&amp;网络爬虫-使用正则表达式抓取网络数据

网络爬虫-使用正则表达式抓取网络数据 关于网络数据抓取不仅仅在iOS开发中有,其他开发中也有,也叫网络爬虫,大致分为两种方式实现 1:正则表达 2:利用其他语言的工具包:java/Python 先来看看网络爬虫的基本原理: 一个通用的网络爬虫的框架如图所示: 网络爬虫的基本工作流程如下: 1.首先选取一部分精心挑选的种子URL: 2.将这些URL放入待抓取URL队列: 3.从待抓取URL队列中取出待抓取在URL,解析DNS,并且得到主机的ip,并将URL对应的网页下载下来,存储进已下载网页库中.

ios开发——常用经典算法OC篇&amp;冒泡/快速

冒泡排序与快速排序 1.序言 ios开发中涉及到算法的地方还真不多,除非你的应用程序真的非常大,或者你想你的应用程序性能非常好才会去想到关于算法方面的性能优化,而在ios开发中真的能用得到的也就是关于排序的,当然如果你是做游戏的话那么你可能会涉及到不少的算法或者优化问题,但是这不是本篇文章讨论的范围. 后面的文章中,我将会给大家详细介绍八大算法. 2.冒泡排序 2.1 引出 前面的两篇博客里讲的插入排序是基于“逐个记录插入”,选择排序是基于“选择”,那么冒泡排序其实是基于“交换”.每次从第一个记

iOS开发——完整项目实战OC篇&amp;百思不得姐第十一天

百思不得姐第十一天 一:模型中没有ID这个属性 为模型增加一个属性ID,设置名字替换 /** id */ @property (nonatomic, copy) NSString *ID; 替换: + (NSDictionary *)replacedKeyFromPropertyName {     return @{@"ID" : @"id"}; } 二:错误的将数组当作字典来用(其实就是没有数据,比如刷新数据已经没有了,或者直接就是0) 通过堆栈定位错误 最后一

iOS开发——项目实战技术OC篇&amp;XMPP简单总结

XMPP简单总结 最近面试被问到了一个问题,笔者当时就懵了:什么XMPP,平时怎么使用,使用过程中遇到什么问题?. 但是还是通过记忆,简单的说了一下自己所知道了,不过那并没有撒卵用,所以你懂的 XMPPFramework是一个OS X/iOS平台的开源项目,使用Objective-C实现了XMPP协议(RFC-3920),同时还提供了用于读写XML的工具,大大简化了基于XMPP的通信应用的开发. 1.关于连接的 1 //此方法在stream开始连接服务器的时候调用 2 - (void)xmppS

iOS开发——完整项目实战OC篇&amp;百思不得姐第八天

百思不得姐第八天 上午 一:监听ScrollView停止两种方法 代码实现滚动的时候:必须要有动画 拖拽实现滚动的时候 二:ScrollView中,对应的X/Y宽高都相等的时候frmae就等一bounds 三:判断View是否在对应的View上面 1:判断父控件 2:看Window是否有值 3:是否创建加载 四:autormaticllyAdjustScrollViewInsets 五:内边距设置 1:tableView尺寸还是屏幕的尺寸(高度) 2:不被导航栏河tabBar挡住(用户能看齐所有