UIPickerView也是一个选择器控件,它比UIDatePicker更加通用,它可以生成单列的选择器,也可生成多列的选择器,而且开发者完全可以自定义选择项的外观,因此用法非常灵活。

UIPickerView直接继承了UIView,没有继承UIControl,因此,它不能像UIControl那样绑定事件处理方法,UIPickerView的事件处理由其委托对象完成。

UIPickerView控件常用的属性和方法如下。

Ø numberOfComponents:获取UIPickerView指定列中包含的列表项的数量。该属性是一个只读属性。

Ø showsSelectionIndicator:该属性控制是否显示UIPickerView中的选中标记(以高亮背景作为选中标记)。

Ø - numberOfRowsInComponent::获取UIPickerView包含的列数量。

Ø - rowSizeForComponent::获取UIPickerView包含的指定列中列表项的大小。该方法返回一个CGSize对象。

Ø - selectRow:inComponent:animated::该方法设置选中该UIPickerView中指定列的特定列表项。最后一个参数控制是否使用动
画。

Ø - selectedRowInComponent::该方法返回该UIPickerView指定列中被选中的列表项。

Ø - viewForRow:forComponent::该方法返回该UIPickerView指定列的列表项所使用的UIView控件。
  UIDatePicker控件只是负责该控件的通用行为,而该控件包含多少列,各列包含多少个列表项则由UIPickerViewDataSource对象负责。开发者必须为UIPickerView设置UIPickerViewDataSource对象,并实现如下两个方法。

Ø - numberOfComponentsInPickerView::该UIPickerView将通过该方法来判断应该包含多少列。

Ø - pickerView:numberOfRowsInComponent::该UIPickerView将通过该方法判断指定列应该包含多少个列表项。

如果程序需要控制UIPickerView中各列的宽度,以及各列中列表项的大小和外观,或程序需要为UIPickerView的选中事件提供响应,都需要为UIPickerView设置UIPickerViewDelegate委托对象,并根据需要实现该委托对象中的如下方法。

Ø - pickerView:rowHeightForComponent::该方法返回的CGFloat值将作为该UIPickerView控件中指定列中列表项的高度。

Ø - pickerView:widthForComponent::该方法返回的CGFloat值将作为该UIPickerView控件中指定列的宽度。

Ø - pickerView:titleForRow:forComponent::该方法返回的NSString值将作为该UIPickerView控件中指定列的列表项的文本标题。

Ø - pickerView:viewForRow:forComponent:reusingView::该方法返回的UIView控件将直接作为该UIPickerView控件中指定列的指
定列表项。

Ø - pickerView:didSelectRow:inComponent::当用户单击选中该UIPickerView控件的指定列的指定列表项时将会激发该方法。

Interface Builder只支持为UIPickerView设置一个属性——Shows Selection Indicator,该属性用于控制是否显示UIPickerView中的选中标记(以高亮背景作为选中标记)。

下面通过程序来介绍UIPickerView 的功能和用法。

††10.12.1  单列选择器

对于单列选择器,只要控制UIPickerView的dataSource对象的numberOfComponentsInPickerView:方法返回1即可。

下面创建一个单列选择器,首先创建一个Single View Application,使用Interface Builder打开应用的界面设计文件,并将一个UIPickerView拖入界面设计文件中,为在程序中访问该控件,需要将该控件绑定到picker IBOutlet属性。

接下来开始修改控制器类,本例打算使用控制器类作为UIPickerView的dataSource和delegate,因此,程序需要让控制器类实现UIPickerViewDataSource、UIPickerViewDelegate两个协议。

修改控制器类的实现代码,主要就是实现UIPickerViewDataSource、UIPickerViewDelegate两个协议中的必要方法,其代码如下。
  程序清单:codes/10/10.12/UIPickerViewTest/UIPickerViewTest /FKViewController.m

  1. @implementation FKViewController
  2. NSArray* books;
  3. - (void)viewDidLoad
  4. {
  5. [super viewDidLoad];
  6. // 创建并初始化NSArray对象
  7. books = [NSArray arrayWithObjects:@"疯狂Android讲义",
  8. @"疯狂iOS讲义", @"疯狂Ajax讲义" , @"疯狂XML讲义", nil];
  9. // 为UIPickerView控件设置dataSource和delegate
  10. self.picker.dataSource = self;
  11. self.picker.delegate = self;
  12. }
  13. // UIPickerViewDataSource中定义的方法,该方法的返回值决定该控件包含多少列
  14. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView
  15. {
  16. return 1;  // 返回1表明该控件只包含1列
  17. }
  18. // UIPickerViewDataSource中定义的方法,该方法的返回值决定该控件指定列包含多少个列表项
  19. - (NSInteger)pickerView:(UIPickerView *)pickerView
  20. numberOfRowsInComponent:(NSInteger)component
  21. {
  22. // 由于该控件只包含一列,因此无须理会列序号参数component
  23. // 该方法返回books.count,表明books包含多少个元素,该控件就包含多少行
  24. return books.count;
  25. }
  26. // UIPickerViewDelegate中定义的方法,该方法返回的NSString将作为UIPickerView
  27. // 中指定列和列表项的标题文本
  28. - (NSString *)pickerView:(UIPickerView *)pickerView
  29. titleForRow:(NSInteger)row forComponent:(NSInteger)component
  30. {
  31. // 由于该控件只包含一列,因此无须理会列序号参数component
  32. // 该方法根据row参数返回books中的元素,row参数代表列表项的编号,
  33. // 因此该方法表示第几个列表项,就使用books中的第几个元素
  34. return [books objectAtIndex:row];
  35. }
  36. // 当用户选中UIPickerViewDataSource中指定列和列表项时激发该方法
  37. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:
  38. (NSInteger)row inComponent:(NSInteger)component
  39. {
  40. // 使用一个UIAlertView来显示用户选中的列表项
  41. UIAlertView* alert = [[UIAlertView alloc]
  42. initWithTitle:@"提示"
  43. message:[NSString stringWithFormat:@"你选中的图书是:%@"
  44. , [books objectAtIndex:row]]
  45. delegate:nil
  46. cancelButtonTitle:@"确定"
  47. otherButtonTitles:nil];
  48. [alert show];
  49. }
  50. @end

复制代码

上面的程序首先初始化了一个NSArray,接下来的关键就是实现了4个用粗体字表示的方法,其中有两个方法来自UIPickerViewDataSource协议,分别用于控制该UIPickerView控件包含多少列、各列包含多少个列表项;另两个方法则来自UIPickerViewDelegate,最后一个粗体字方法负责为UIPickerView控件的选中事件提供响应——当用户选中该UIPickerView的某个列表项时,系统将会自动激发该方法,该方法的实现逻辑就是使用UIAlertView显示用户选择的图书。
  编译、运行该程序,可以看到如图10.46所示的效果。
   
  
    图10.46  单列UIPickerView
  
   
  如果用户选择某个列表项,程序将会弹出如图10.47所示的UIAlertView警告框。
   
                              
  
     图10.47  选中指定项
   
  10.12.2  多列选择器   对单列选择器而言,只要控制UIPickerView的dataSource对象的numberOfComponentsInPickerView:方法返回大于1的整数即可。
  本节创建一个多列选择器,首先创建一个Single View Application,使用Interface Builder打开应用的界面设计文件,并将一个UIPickerView拖入界面设计文件中,为在程序中访问该控件,需要将该控件绑定到picker IBOutlet属性。

接下来修改控制器类,本例打算使用控制器类作为UIPickerView的dataSource和delegate,因此程序需要让控制器类实现UIPickerViewDataSource、UIPickerViewDelegate两个协议。

修改控制器类的实现代码,主要就是实现UIPickerViewDataSource、UIPickerViewDelegate两个协议中的必要方法,其代码如下。
  程序清单:codes/10/10.12/MultiPickerTest/MultiPickerTest/FKViewController.m

  1. @implementation FKViewController
  2. NSArray* books;
  3. NSArray* authors;
  4. - (void)viewDidLoad
  5. {
  6. [super viewDidLoad];
  7. // 创建并初始化两个NSArray对象,分别作为两列的数据
  8. authors = [NSArray arrayWithObjects:@"泰戈尔",
  9. @"冯梦龙", @"李刚" , nil];
  10. books = [NSArray arrayWithObjects:@"飞鸟集" , @"吉檀迦利"
  11. , @"醒世恒言",@"喻世明言", @"警世通言", @"疯狂Android讲义",
  12. @"疯狂iOS讲义", @"疯狂Ajax讲义" , @"疯狂XML讲义", nil];
  13. self.picker.dataSource = self;
  14. self.picker.delegate = self;
  15. }
  16. // UIPickerViewDataSource中定义的方法,该方法返回值决定该控件包含多少列
  17. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView
  18. {
  19. return 2;  // 返回2表明该控件只包含2列
  20. }
  21. // UIPickerViewDataSource中定义的方法,该方法的返回值决定该控件指定列包含多少个列表项
  22. - (NSInteger)pickerView:(UIPickerView *)pickerView
  23. numberOfRowsInComponent:(NSInteger)component
  24. {
  25. // 如果是第一列,返回authors中元素的个数
  26. // 即authors包含多少个元素,第一列就包含多少个列表项
  27. if (component == 0) {
  28. return authors.count;
  29. }
  30. // 如果是其他列,返回books中元素的个数。
  31. // 即books包含多少个元素,其他列(只有第二列)包含多少个列表项
  32. return books.count;
  33. }
  34. // UIPickerViewDelegate中定义的方法,该方法返回的NSString将作为
  35. // UIPickerView中指定列和列表项上显示的标题
  36. - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:
  37. (NSInteger)row forComponent:(NSInteger)component
  38. {
  39. // 如果是第一列,返回authors中row索引处的元素
  40. // 即第一列的列表项标题由authors集合元素决定
  41. if (component == 0) {
  42. return [authors objectAtIndex:row];
  43. }
  44. // 如果是其他列(只有第二列),返回books中row索引处的元素
  45. // 即第二列的列表项标题由books集合元素决定
  46. return [books objectAtIndex:row];
  47. }
  48. // 当用户选中UIPickerViewDataSource中指定列和列表项时激发该方法
  49. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:
  50. (NSInteger)row inComponent:(NSInteger)component
  51. {
  52. NSArray* tmp  = component == 0 ? authors: books;
  53. NSString* tip = component == 0 ? @"作者": @"图书";
  54. // 使用一个UIAlertView来显示用户选中的列表项
  55. UIAlertView* alert = [[UIAlertView alloc]
  56. initWithTitle:@"提示"
  57. message:[NSString stringWithFormat:@"你选中的%@是:%@,"
  58. , tip, [tmp objectAtIndex:row]]
  59. delegate:nil
  60. cancelButtonTitle:@"确定"
  61. otherButtonTitles:nil];
  62. [alert show];
  63. }
  64. // UIPickerViewDelegate中定义的方法,该方法返回的NSString将作为
  65. // UIPickerView中指定列的宽度
  66. - (CGFloat)pickerView:(UIPickerView *)pickerView
  67. widthForComponent:(NSInteger)component
  68. {
  69. // 如果是第一列,宽度为90
  70. if (component == 0) {
  71. return 90;
  72. }
  73. return 210;  // 如果是其他列(只有第二列),宽度为210
  74. }
  75. @end

复制代码

该程序与前一个程序基本相似,同样需要实现上面4个方法,只是numberOfComponentsInPickerView:方法返回了2,因此,该UIPickerView包含两列,程序创建了两个NSArray,分别为两列提供数据项。除此之外,上面的程序还实现了一个pickerView:widthForComponent:方法,该方法的返回值控制UIPickerView中各列的宽度。
  编译、运行该程序,可以看到如图10.48所示的两列选择器。
  

如果用户选中指定的列表项,该应用同样会弹出UIAlertView显示用户的选择,弹出的警告框与图10.47类似。

††10.12.3  相互依赖的多列选择器

10.12.2节的示例虽然是一个两列的UIPickerView控件,但该控件的两列基本没有任何关系,选择第一列的作者时,第二列的图书不会动态更新——在某些情况下,这是允许的。但在某些情况下,我们需要第二列的列表项依赖第一列的选择,即当第一列选择作者时,第二列只显示该作者的图书。

为了让第二列能根据第一列的选择动态加载,程序需要用户选择第一列的事件,并根据该事件动态加载第二列的数据,然后强制重新加载UIDatePicker的第二列列表项。

下面创建一个相互依赖的多列选择器,首先创建一个Single View Application,使用Interface Builder打开应用的界面设计文件,并将一个UIPickerView拖入界面设计文件中,为在程序中访问该控件,需要将该控件绑定到picker IBOutlet属性。

接下来开始修改控制器类,本例使用控制器类作为UIPickerView的dataSource和delegate,因此,程序需要让控制器类实现UIPickerViewDataSource、UIPickerViewDelegate两个协议。

修改控制器类的实现代码,主要就是实现UIPickerViewDataSource、UIPickerViewDelegate两个协议中的必要方法,其代码如下。
  程序清单:codes/10/10.12/MultiPickerTest2/MultiPickerTest2/FKViewController.m

  1. @implementation FKViewController
  2. NSDictionary* books;
  3. NSArray* authors;
  4. // selectedAuthor保存当前选中的作者
  5. NSString* selectedAuthor;
  6. - (void)viewDidLoad
  7. {
  8. [super viewDidLoad];
  9. // 创建并初始化NSDictionary对象
  10. books = [NSDictionary dictionaryWithObjectsAndKeys:
  11. [NSArray arrayWithObjects:@"飞鸟集" , @"吉檀迦利", nil]
  12. , @"泰戈尔",
  13. [NSArray arrayWithObjects:@"醒世恒言",@"喻世明言"
  14. , @"警世通言", nil] , @"冯梦龙",
  15. [NSArray arrayWithObjects:@"疯狂Android讲义",
  16. @"疯狂iOS讲义", @"疯狂Ajax讲义" , @"疯狂XML讲义", nil]
  17. , @"李刚" ,nil];
  18. // 使用authors保存books所有key组成的NSArray排序后的结果
  19. authors = [[books allKeys] sortedArrayUsingSelector:
  20. @selector(compare:)];
  21. // 设置默认选中的作者authors中的第一个元素
  22. selectedAuthor = [authors objectAtIndex:0];
  23. self.picker.dataSource = self;
  24. self.picker.delegate = self;
  25. }
  26. // UIPickerViewDataSource中定义的方法,该方法的返回值决定该控件包含多少列
  27. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView
  28. {
  29. return 2;  // 返回2表明该控件只包含2列
  30. }
  31. // UIPickerViewDataSource中定义的方法,该方法的返回值决定该控件指定列包含多少个列表项
  32. - (NSInteger)pickerView:(UIPickerView *)pickerView
  33. numberOfRowsInComponent:(NSInteger)component
  34. {
  35. // 如果是第一列,返回authors中元素的个数
  36. // 即authors包含多少个元素,第一列包含多少个列表项
  37. if (component == 0) {
  38. return authors.count;
  39. }
  40. // 如果是其他列(只有第二列),
  41. // 返回books中selectedAuthor对应的NSArray中元素的个数
  42. return [[books objectForKey:selectedAuthor] count];
  43. }
  44. // UIPickerViewDelegate中定义的方法,该方法返回的NSString将作为
  45. // UIPickerView中指定列和列表项上显示的标题
  46. - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:
  47. (NSInteger)row forComponent:(NSInteger)component
  48. {
  49. // 如果是第一列,返回authors中row索引处的元素
  50. // 即第一列的元素由authors集合元素决定
  51. if (component == 0) {
  52. return [authors objectAtIndex:row];
  53. }
  54. // 如果是其他列(只有第二列),
  55. // 返回books中selectedAuthor对应的NSArray中row索引处的元素
  56. return [[books objectForKey:selectedAuthor] objectAtIndex:row];
  57. }
  58. // 当用户选中UIPickerViewDataSource中指定列和列表项时激发该方法
  59. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
  60. inComponent:(NSInteger)component
  61. {
  62. if(component == 0)
  63. {
  64. // 改变被选中的作者
  65. selectedAuthor = [authors objectAtIndex:row];
  66. // 控制重写加载第二个列表,根据选中的作者来加载第二个列表
  67. [self.picker reloadComponent:1];
  68. }
  69. NSArray* tmp  = component == 0 ? authors:
  70. [books objectForKey:selectedAuthor];
  71. NSString* tip = component == 0 ? @"作者": @"图书";
  72. // 使用一个UIAlertView来显示用户选中的列表项
  73. UIAlertView* alert = [[UIAlertView alloc]
  74. initWithTitle:@"提示"
  75. message:[NSString stringWithFormat:@"你选中的%@是:%@,"
  76. , tip , [tmp objectAtIndex:row]]
  77. delegate:nil
  78. cancelButtonTitle:@"确定"
  79. otherButtonTitles:nil];
  80. [alert show];
  81. }
  82. // UIPickerViewDelegate中定义的方法,该方法返回的NSString将作为
  83. // UIPickerView中指定列的宽度
  84. - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:
  85. (NSInteger)component
  86. {
  87. // 如果是第一列,宽度为90
  88. if (component == 0) {
  89. return 90;
  90. }
  91. return 210;  // 如果是其他列(只有第二列),宽度为210
  92. }
  93. @end

复制代码

上面控制器类的实现部分与前一个示例中控制器类的实现部分大致相同,关键就是程序中的粗体字代码。本程序采用了NSDictionary分别保存NSPickerView控件中的两列数据,NSDictionary的所有key组成的集合作为第1列的数据,当用户选中第一列的某个作者后,程序取出NSDictionary中该作者对应的图书集合作为第二列的数据。这就可以让第二列数据随第一列的选择动态改变。

UIPickerView(选择器)的更多相关文章

  1. iOS:UIPickerView选择器的使用

    通过UIPickerView选择器做的一个类似于密码锁的日期时间表 源码如下: #import <UIKit/UIKit.h> @interface ViewController : UI ...

  2. UIPickerView选择器的使用方法

    UIPickerView是选择列表内容的控件 使用方法与UITableView类似 都需要用array传入数据 用Delegate DataSource中的代理方法实现各种显示功能 @interfac ...

  3. UIPickerView 循环滚动(一种假象)

    因为网上没有查到相关方法,故而采用一种假象的方法来实现,选项循环滚动 - (void)viewDidLoad { [super viewDidLoad]; /** UIPickerView 选择器 * ...

  4. UIPickerView基本用法

    #import "ViewController.h" #import <UIKit/UIKit.h> @interface ViewController : UIVie ...

  5. iOS-UI-UI控件概述

    以下列举一些在开发中可能用得上的UI控件: IBAction和IBOutlet,UIView 1 @interface ViewController : UIViewController 2 3 @p ...

  6. iOS中的UI

    • 不管你是学习android开发还是iOS开发• 都建议先学习UI,原因如下:UI是app的根基:⼀一个app应该是先有UI界⾯面,然后在UI的基础上增加实⽤用功能 UI相对简单易学:UI普遍是学 ...

  7. ios 中的UI控件学习总结(1)

    UIKit框架提供了非常多功能强大又易用的UI控件 下面列举一些在开发中可能用得上的UI控件 UIButton 按钮 UILabel 文本标签 UITextField 文本输入框 UIImageVie ...

  8. ios 学习路线总结

    学习方法 面对有难度的功能,不要忙着拒绝,而是挑战一下,学习更多知识. 尽量独立解决问题,而不是在遇到问题的第一想法是找人. 多学习别人开源的第三方库,能够开源的库一定有值得学习的地方,多去看别的大神 ...

  9. iOS开发--知识点总结

    1 .全局变量,变量名前加下划线.和系统一致. 2 . nil指针为空   @“”字符串为空 (内容为空)       ==  判断内存地址   基本变量    对于一些基本类型 可以使用==来判断, ...

随机推荐

  1. IPAddress

    Console.WriteLine("BitConverter.IsLittleEndian = {0}", BitConverter.IsLittleEndian); Conso ...

  2. openwrt开发

    之前写过一篇日志,是关于如何搭建自己的OpenWRT开发环境.经过最近一段时间的开发学习和实践,对OpenWRT环境的开发有了一定的了解.在这里将我的开发心得做个整理. 1.搭建开发环境 首先,我们需 ...

  3. bzoj3503

    显然知道第一行就可以只道整个矩阵但n<=40,搜索是不行的,我们设第一行为x1~xm可以由轻易由第一行未知数推出第n+1行,这一步我们可以压成二进制位(因为只和奇偶有关)显然n+1行必须是0,由 ...

  4. [POJ 2019] Cornfields

    Cornfields Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5516   Accepted: 2714 Descri ...

  5. ASP.NET MVC3学习心得-----表单和HTML辅助方法

    5.1表单的使用 5.1.1  action和method的特性 表单是包含输入元素的容器,包含按钮.复选框.文本框等元素,表单的这些输入元素使得用户能够向页面中输入信息,并把输入信息提交给服务器.A ...

  6. 在ASP.NET MVC中实现基于URL的权限控制

    本示例演示了在ASP.NET MVC中进行基于URL的权限控制,由于是基于URL进行控制的,所以只能精确到页.这种权限控制的优点是可以在已有的项目上改动极少的代码来增加权限控制功能,和项目本身的耦合度 ...

  7. Read ListViewItem content from another process z

    Normal Windows GUI applications work with messages that are sent to a window or control and the cont ...

  8. LightOJ 1370 Bi-shoe and Phi-shoe 欧拉函数+线段树

    分析:对于每个数,找到欧拉函数值大于它的,且标号最小的,预处理欧拉函数,然后按值建线段树就可以了 #include <iostream> #include <stdio.h> ...

  9. 开发工具安装运行bug总结

    如果tomcat出现闪退 在startup.bat--编辑   在文件最后加上 pause  ,再跑一次,可以看到闪退的原因. 一般是环境变量问题,只需要打开starup.bat--编辑,最方件的最上 ...

  10. 【JS】Intermediate2:Events and Callbacks

    event-driven :waiting for and reacting to events 2.page loads, user interacts (clicks, hovers, chang ...