UIPickerView 的使用

来源:互联网 发布:保险代理软件 编辑:程序博客网 时间:2024/04/28 03:59

转自:http://blog.csdn.net/nono_love_lilith/article/details/7527794


Date Picker控件和Picker View控件其实也是算比较常用到视图。

以下根据红柚子上得几个例子:

分别从(日期选取器)Date Picker   ——>单部件选取器——>多部件选取器——>依赖组建选取器。

这边我们不是一步步从创建一个项目开始,毕竟有过前面两三次的实践后,

对于如何选择性的创建一个最合适的应用基础模板已经很简单了。

这边为了方便视图切换,我们用了前面用到过的TabBarController视图控制器。

下面是对以上4种分别举个小例子


一:日期选取器


就是很简单一个日期组建,触摸滚轮可以选取时间,点击确认弹出你选中得时间。

(不过不知道什么情况,感觉有貌似我这个显示怎么出了个8小时的时差~~,不知道是模拟器还是哪边要设置,比如Android会有个设置系统时区什么的)。

我们先不管这个,这几界面就很简单。我们就看到一个datePicker控件和一个确认控件么(这个都知道在xib文件右边拖拽进来吧)

[cpp] view plaincopy
  1. //  
  2. //  NonoFirstViewController.h  
  3. //  MultiViews  
  4. //  
  5. //  Created by Nono on 12-4-19.  
  6. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  7. //  
  8.   
  9. #import <UIKit/UIKit.h>  
  10.   
  11. @interface NonoFirstViewController : UIViewController  
  12. {  
  13.     UIDatePicker *datePicker;  
  14.    
  15. }  
  16. @property(nonatomic, retain) IBOutlet UIDatePicker *datePicker;//日期选取器  
  17. -(IBAction)buttonPressed:(id)sender;//按钮操作  
  18. @end  

头文件我们定义了这一个输出口和一个按钮事件
[cpp] view plaincopy
  1. //  
  2. //  NonoFirstViewController.m  
  3. //  MultiViews  
  4. //  
  5. //  Created by Nono on 12-4-19.  
  6. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  7. //  
  8. #import "NonoFirstViewController.h"  
  9.   
  10. @implementation NonoFirstViewController  
  11. @synthesize datePicker;  
  12. -(IBAction)buttonPressed:(id)sender  
  13. {  
  14.     NSDate * selected = [self.datePicker date];//获取选取时间  
  15.     NSString *date = [[NSString alloc] initWithFormat:@"你选择了:%@",selected];  
  16.     UIAlertView * alterView = [[UIAlertView alloc] initWithTitle:@"时间提示" message:date delegate:self cancelButtonTitle:@"确定" otherButtonTitles: nil];  
  17.     [alterView show];  
  18.       
  19. }  
  20.   
  21. - (void)viewDidLoad  
  22. {  
  23.     [super viewDidLoad];  
  24.     NSDate *now = [[NSDate alloc] init];  
  25.     [datePicker setDate:now animated:YES];  
  26.     // Do any additional setup after loading the view from its nib.  
  27. }  
  28.   
  29.   
  30.   
  31. @end  

实现文件也很简单,基本没什么说的,因为这个控件我们跳进datePicker的头文件,发现其实他就是一种pickerView的封装实现。

对于我们来说,使用范围就比较局限性。看他的类名我们就知道了。

因此很多时候,我们都会需要自定义Picker View


二:Picker View组件


这个就是一个单部件的picker View。

根据我们的思路或是一些开发经验。

看到这么一个东西,大致可以知道:第一,有个展示界面(也就是我们拖进去的PickerView)

第二,需要有填充这个界面的数据源

第三,需要一个我们对该控件相关操作的控制者。

有过Android开发的朋友也该很容易联想到一个东西,就是Adapter,适配器。

其实ios这个也是差不多。

这边提一点,其实IOS这种适配模式等你接触后,就会恍然大悟的发现,就这么一个模式。

一个视图,实现一个数据源协议,实现一个(控制器代理)。

基本所有类似组建得表现形式和操作都是这三者的结合。(MVC模式啊,代理模式啊什么,这算吧,也挺形象了)

废话不多说,先看下头文件

[cpp] view plaincopy
  1. //  
  2. //  NonoSecondViewController.h  
  3. //  MultiViews  
  4. //  
  5. //  Created by Nono on 12-4-19.  
  6. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  7. //  
  8.   
  9. #import <UIKit/UIKit.h>  
  10.   
  11. @interface NonoSecondViewController : UIViewController  
  12. <UIPickerViewDelegate,UIPickerViewDataSource>//协议:选取器得数据源,和委托  
  13. {  
  14.     UIPickerView * pickerView;  
  15.     NSArray *pickerData;  
  16. }  
  17. @property(nonatomic,retain) NSArray *pickerData;  
  18. @property(nonatomic, retain) IBOutlet UIPickerView  *pickerView;  
  19. -(IBAction)buttonPressed:(id)sender;  
  20.   
  21. @end  
申明了需要实现的两个 <UIPickerViewDelegate,UIPickerViewDataSource>

就是我们上面提到的。

多了一个属性申明 一个数组。等会用于存放数据源。

[cpp] view plaincopy
  1. //  
  2. //  NonoSecondViewController.m  
  3. //  MultiViews  
  4. //  
  5. //  Created by Nono on 12-4-19.  
  6. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  7. //  
  8.   
  9. #import "NonoSecondViewController.h"  
  10.   
  11. @implementation NonoSecondViewController  
  12. @synthesize pickerData;  
  13. @synthesize pickerView;  
  14.   
  15. //实现申明方法  
  16. -(void)buttonPressed:(id)sender  
  17. {  
  18.     NSInteger row = [pickerView selectedRowInComponent:(0)];  
  19.     NSString *selected = [pickerData objectAtIndex:row];  
  20.     NSString *title = [[NSString alloc] initWithFormat:@"你选择的:%@!",selected];  
  21.     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:title delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];  
  22.     [alert show];  
  23.       
  24. }  
  25.   
  26. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  27. {  
  28.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  29.     if (self) {  
  30.         // Custom initialization  
  31.     }  
  32.     return self;  
  33. }  
  34.   
  35. - (void)viewDidLoad  
  36. {  //初始化数据源数据  
  37.        [super viewDidLoad];  
  38.     NSArray *array = [[NSArray alloc] initWithObjects:@"陈凯", @"至尊宝",@"菩提老祖",@"二当家",@"紫霞仙子",@"蜗牛",nil];  
  39.     self.pickerData = array;  
  40.       
  41.   
  42.       // Do any additional setup after loading the view from its nib.  
  43. }  
  44.   
  45. - (void)viewDidUnload  
  46. {  
  47.     [super viewDidUnload];  
  48.     self.pickerData = nil;  
  49.     self.pickerView = nil;  
  50.     // Release any retained subviews of the main view.  
  51.     // e.g. self.myOutlet = nil;  
  52. }  
  53.   
  54. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  55. {  
  56.     return (interfaceOrientation == UIInterfaceOrientationPortrait);  
  57. }  
  58.   
  59. #pragma mark -  
  60. #pragma mark Picker Data Source Methods  
  61. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView  
  62. {  
  63.     return (1);  
  64. }  
  65. - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component  
  66. {    
  67.     return [pickerData count];  
  68. }  
  69. #pragma mark Picker Delegate Methods  
  70. //书上介绍说这里面得委托方法是可选得(delegate中用optional修饰),实际上我们至少要实现一个委托方法  
  71. - (NSString *)pickerView:(UIPickerView *)pickerView   
  72.              titleForRow:(NSInteger)row   
  73.             forComponent:(NSInteger)component  
  74. {  
  75.     return [pickerData objectAtIndex:row];  
  76. }  
  77.   
  78. @end  
主要看下#pragma mark下得三个方法(pragma干嘛使,其实也不太明白,目前知道感觉就如一个标记东西,不写其实也没关系,写了我们可以看得比较明白

,以下使我们实现的协议方法。述说貌似对其有个更好的解释,大家可以google或是看书。)

首先,必须实现的两个数据源协议中的方法。

第一个:- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return (1);//返回在这个pickerView中得部件个数
}

这是什么意思呢?以我的简单理解说下吧。

我们整个视图是一个PickerView,里面可以有单个货多个部件(什么意思?看上面两个截图,

DatePicker中4个部件,至尊宝中就是一个部件)

好吧,应该了解了。这个方法得返回值就是返回你所要显示得部件个数。

这边我们知道,我们就一个部件,也只需显示一个部件。

第二个:- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{  
    return [pickerData count];
}

返回每个部件中要显示数据的条数。说白了就是返回你要填充这个部件的数据源中数据元素的个数,这边就是数组的大小么。

以上两个是数据源的协议方法实现,下面这个是pickerView委托中方法的实现。

当然,这个委托协议中的我们能看到很多方法,但是是可选的,可以根据我们得需要来实现。

但是上面代码也说了,虽然可选,但是基本都会要实现这个方法。

- (NSString *)pickerView:(UIPickerView *)pickerView 
             titleForRow:(NSInteger)row 
            forComponent:(NSInteger)component
{
    return [pickerData objectAtIndex:row];
}

因为我们知道,数据源协议两个方法只不过是和我们得视图做了一个关联,

如何把数据显示出来,就靠这个方法了。

单个部件的基本就是这么简单。


三:多部件控件以及依赖组件

这两个就一起说算了,因为差不多。

       

两个滚轮,就是多部件组件形式(当然你可以更多)。

组建的相互依赖,也很简单,既当我我第一个滚轮滚到鸟类时,第二个滚轮中得数据是鸟;

鱼儿的时候是鲤鱼鲨鱼。前者就像一个父节点一样。

下面我来定义头文件

[cpp] view plaincopy
  1. //  MultiViews  
  2. //  
  3. //  Created by Nono on 12-4-20.  
  4. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  5. //  
  6.   
  7. #import <UIKit/UIKit.h>  
  8.   
  9. #define mFather   0  
  10. #define mChilder  1  
  11.   
  12. @interface NonoDependentOnViewController : UIViewController<UIPickerViewDelegate,UIPickerViewDataSource>  
  13. {  
  14.     UIPickerView *dependentPickerView;  
  15.     NSArray *fatherArray;  
  16.     NSArray *childeArray;  
  17.     NSDictionary *dictionary;  
  18. }  
  19.   
  20. @property(retain ,nonatomic) IBOutlet UIPickerView *dependentPickerView;  
  21. @property(retain,nonatomic) NSArray *fatherArray;  
  22. @property(retain,nonatomic) NSArray *childerArray;  
  23. @property(retain, nonatomic) NSDictionary *dictionary;  
  24.   
  25. - (IBAction)buttonPressed:(id)sender;  
  26.   
  27. @end  

几个属性,fatherArray就是用于存放第一个滚轮的数据源数组(比如鱼儿,鸟类),childerArray用于存放第二个滚轮的数据源组

实现文件

[cpp] view plaincopy
  1. //  
  2. //  NonoDependentOnViewController.m  
  3. //  MultiViews  
  4. //  
  5. //  Created by Nono on 12-4-20.  
  6. //  Copyright (c) 2012年 NonoWithLilith. All rights reserved.  
  7. //  
  8.   
  9. #import "NonoDependentOnViewController.h"  
  10.   
  11.   
  12. @implementation NonoDependentOnViewController  
  13. @synthesize dependentPickerView;  
  14. @synthesize fatherArray;  
  15. @synthesize childerArray;  
  16. @synthesize dictionary;  
  17. //按钮点击效果  
  18. - (IBAction)buttonPressed:(id)sender  
  19. {     
  20. <span style="white-space:pre">  </span>。。。。  
  21. }  
  22.   
  23. - (void)viewDidLoad  
  24. {  
  25.     [super viewDidLoad];  
  26.       
  27.     NSBundle *bundle = [NSBundle mainBundle];//此调用的返回的束对象表示我们的应用程序  
  28.     NSString *path = [bundle pathForResource:@"Fcsource" ofType:@"plist"];  
  29.     NSDictionary *dic = [[NSDictionary alloc] initWithContentsOfFile:path];  
  30.     self.dictionary = dic;  
  31.       
  32.     NSArray *rootArray = [self.dictionary allKeys];   
  33.     NSArray *root = [rootArray sortedArrayUsingSelector:@selector(compare:)];  
  34.     self.fatherArray = root;  
  35.       
  36.     NSString *fatherSec = [self.fatherArray objectAtIndex:0];  
  37.     NSArray *array = [self.dictionary objectForKey:fatherSec];  
  38.     self.childerArray = array;  
  39.       
  40.     // Do any additional setup after loading the view from its nib.  
  41. }  
  42.   
  43. #pragma mark -  
  44. //数据源协议方法实现  
  45. // returns the number of 'columns' to display.  
  46. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView  
  47. {  
  48.     return 2;  
  49. }  
  50.   
  51. // returns the # of rows in each component..  
  52. - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component  
  53. {  
  54.     if (component == mFather) {  
  55.         return [self.fatherArray count];  
  56.     }else {  
  57.         return [self.childerArray count];  
  58.     }  
  59. }  
  60.   
  61.   
  62. //选取器委托方法实现  
  63. //显示在view上  
  64. - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component  
  65. {  
  66.     if(component == mFather){  
  67.         return [self.fatherArray objectAtIndex:row];  
  68.     }else {  
  69.         return [self.childerArray objectAtIndex:row];  
  70.     }  
  71. }  
  72.   
  73. //一个选取器选取改变另一个依赖得选择器  
  74. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component  
  75. {  
  76.     if (component == mFather) {  
  77.         NSString *string = [self.fatherArray objectAtIndex:row];  
  78.         NSArray *array = [self.dictionary objectForKey:string];  
  79.         self.childerArray = array;  
  80.         [dependentPickerView selectRow:0 inComponent:mChilder animated:YES];  
  81.         [dependentPickerView reloadComponent:mChilder];  
  82.     }  
  83.       
  84.     NSLog(@"触发依赖");  
  85. }  
  86. //改变两个部件宽度  
  87. - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component  
  88. {  
  89.     if(component == mFather)  
  90.         return (100);  
  91.     return 200;  
  92. }  
  93.   
  94. @end  
(几个默认的我们这边不提及到得方法我delete掉了)

这边我们涉及下一个小的api知识,就是用plist文件存储数据。这个以后也会是常用的。

基本步骤是:1.新定义一个plist文件

2.打开plist文件自定义一些数据源

大致界面就是:




 

[cpp] view plaincopy
  1. NSBundle *bundle = [NSBundle mainBundle];//此调用的返回的束对象表示我们的应用程序  
  2. NSString *path = [bundle pathForResource:@"Fcsource" ofType:@"plist"];  
  3. NSDictionary *dic = [[NSDictionary alloc] initWithContentsOfFile:path];  
  4. self.dictionary = dic;  

其实就是读取了这个一个文件,后一NSDictionary的对象保存起来。因为我们以xml形式打开这个plist文件

会发现,这货最外层得标签就是一个<dict>

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
  3. <plist version="1.0">  
  4. <dict>  
  5.     <key>鱼儿</key>  
  6.     <array>  
  7.         <string>鲤鱼</string>  
  8.         <string>鲨鱼</string>  
  9.     </array>  
  10.     <key>鸟类</key>  
  11.     <array>  
  12.         <string>大鸟</string>  
  13.         <string>小鸟</string>  
  14.     </array>  
  15. </dict>  
  16. </plist>  

allkeys后返回所有key对应得value放入一个数组,书本上又对数组做了下排序操作。

默认我们选取了索引为0的父源,以及对应的子源。

然后继续看数据源协议得两个方法,略微有点变化

第一个不说了,返回部件数为2;

第二个// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if (component == mFather) {
        return [self.fatherArray count]; //如果是父部件,返回填充父部件数据源个数
    }else {
        return [self.childerArray count];//子部件。。。。。。
    }
}


同理的,对于pickerView委托方法中这个方法也很好理解

//显示在view上
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    if(component == mFather){
        return [self.fatherArray objectAtIndex:row];
    }else {
        return [self.childerArray objectAtIndex:row];
    }
}

最主要是这个委托方法实现,也是依赖组件的核心

[cpp] view plaincopy
  1. //一个选取器选取改变另一个依赖得选择器  
  2. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component  
  3. {  
  4.     if (component == mFather) {  
  5.         NSString *string = [self.fatherArray objectAtIndex:row];  
  6.         NSArray *array = [self.dictionary objectForKey:string];  
  7.         self.childerArray = array;  
  8.         [dependentPickerView selectRow:0 inComponent:mChilder animated:YES];  
  9.         [dependentPickerView reloadComponent:mChilder];  
  10.     }  
  11.       
  12.     NSLog(@"触发依赖");  
  13. }  

看方法名我们可以知道是部件上某条数据(row)被选中后。可以做出相应得操作。

这边我们知道,我们选中了不同得父源后,需要显示相应的子源。

因此我们可以做一些如上得代码操作。


好了。选取期组件初步基本就这些。

这个列子还是好久前写的,因此大伙看到没有 release呵呵,因为我那会创建还是用得ARC。

说简单点,核心就三点:

一个pickerView,一个数据源协议,一个委托协议。



原创粉丝点击