Ios5(五)多视图pickers应用程序实现
一. 基本概念:
1. Pickers:是带有能够旋转的刻度盘的控件。可以配置显示一个多多个刻度盘。默认情况下,只显示文本列表,但是也能够显示图像;
2. 本节实现带有五个标签的选取器应用程序;
3. 选取器的使用并不知识从IB中拖入就能使用(日期选取器例外),还要为选取器提供选取器委托和数据源;
4. 选取器委托最重要的任务:确定为每个组件中每一行绘制的实际内容。选取器要求委托在特定组件的特定位置绘制一个字符串或一个视图。选取器从委托获得数据;
5. 选取器通过数据源获得组件数和每个组件的行数;
6. 很多情况下,数据源和委托是一个对象,该对象也是选取器视图的视图控制器;
7. 数据源属于MVC的C,真正的工作是从模型中检索数据,并传递给检索器;
二. 实例:
1. 创建Empty的空项目;
注:我们应该创建一个根视图控制器来管理切换应用程序其他视图的过程。这次无需自己创建类,可以使用xcode提供的UITabBarController来作为跟控制器;
2. 创建五个带有xib文件的视图控制器;
3. 添加根视图控制器;
①将代理作为UITabBarController实例的管理类,声明一个输出口:
@property (strong, nonatomic) IBOutlet UITabBarController*rootController;
@synthesizerootController;
[[NSBundle mainBundle] loadNibNamed:@"TabBarController" owner:self options:nil];
[self.window addSubview:rootController.view];
注:这里没有在代码中直接创建视图控制器,而是上载了一个包含视图控制器的xib文件。
4. 创建TabBarController
①创建一个empty的user interface文件,
②从对象库中添加一个Tab Bar Controller;其中的标签栏控件是根控制器;下面还有两个默认的视图控制器和两个标签;
③将身份检查器的Custom class改为我们的代理类:BIDAppDelegate;然后将fils‘s owner的rootController与dock中的TabBarController建立连接;
④添加其他三个标签栏,TabBarItem;
⑤点击第一个视图控制器,将其NIBName指定为BIDDataPickerVIewController控制器,将身份检查器的CustomClass设置为BIDDataPickerVIewController,同样设置其他四个;
⑤修改每个TabBarItem对应的title和图标;
5. 实现日期选取器:
① 首先在控制器文件中创建一个输出口和一个操作,输出口用于从日期选取器获取值,操作用于触发一个警告;
@property (strong,nonatomic) IBOutlet UIDatePicker *dataPicker;
- (IBAction)buttonPressed:(id)sender;
② 在xib文件中,首先调整视图,将Bottom Bar设置为Tab Bar,在库中拖动Date Picker到视图中;并设置DataPicker的属性,Constraints,最大值和最小值;
③ 加入一个按钮,并分别将按钮和datePicker与输出口和动作:
synthesize dataPicker;
@synthesize nowData;
- (IBAction)buttonPressed:(id)sender{
NSDate*date = [dataPicker date];
NSString*str = [NSString stringWithFormat:@"thedata is %@",date];
UIAlertView *allert = [[UIAlertView alloc] initWithTitle:@"theData" message:str delegate:nil cancelButtonTitle:@"OK,Iknow" otherButtonTitles: nil];
[allert show];
}
注:日期的选取器是不需要数据源和代理的,其内嵌数据源和代理,我们只需要获取其数据就可以了,获取数据的方法:
NSDate*date = [dataPicker date];
6. 实现单组件选取器;
①. 选取器本身不会保存任何数据,数据源和委托相互协作来提供数据。
②. 声明输出口和操作:、
@property (weak, nonatomic) IBOutlet UIPickerView*simplePicker;
- (IBAction)dataSelected:(id)sender;
③. 构建视图:首先将View属性检查器的Bottom Bar设置为TabBar;从库中拖出一个PickerView;将DataSource和Delegate连接到file’s owner;将pickerView和按钮与声明的属性相连;
④. 实现初始化和按钮的事件;
- (IBAction)dataSelected:(id)sender{
NSIntegerrow = [simplePicker selectedRowInComponent:0];
NSString*data = [pickerData objectAtIndex:row];
NSString*str = [[NSString alloc] initWithFormat:@"thedata is %@",data];
UIAlertView*allert = [[UIAlertView alloc] initWithTitle:@"hello" message:strdelegate:nil cancelButtonTitle:@"OK,Iknow" otherButtonTitles: nil];
[allert show];
}
- (void)viewDidLoad
{
[super viewDidLoad];
pickerData =[[NSArray alloc] initWithObjects:@"yang",@"Wang",@"shao",@"one",@"two",@"three",@"four",@"five", nil];
}
⑤. 实现数据源和委托:
#pragmamark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView{
return 1;
}
- (NSInteger)pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component{
return [pickerData count];
}
#pragma mark Picker Delegate Methods
- (NSString*)pickerView:(UIPickerView*)pickerView titleForRow:(NSInteger)rowforComponent:(NSInteger)component{
return [pickerData objectAtIndex:row];
}
⑥ 常规的选取器无法告诉我们其包含的数据。
⑦ 与数据源方法不同,所有的委托方法都是可选的。可选有一定的欺骗性,因为必须要实现至少一个委托方法,一般是实现返回值为NSString的,要在选取器中显示文本之外的内容,必须实现一种不同的方法;
7. 多组件选取器:无依赖关系
与单组件区别不大;
8. 实现有依赖关系的多组件选取器:显示一组美国的州和对应的邮政编码;
① 首先声明两个数组,一个字典,pickerView的输出口,按钮Action口,显示两个协议;
@property (strong,nonatomic) IBOutlet UIPickerView*picker;
@property (strong,nonatomic) NSDictionary*stateZips;
@property (strong,nonatomic) NSArray*states;
@property (strong,nonatomic) NSArray *zips;
- (IBAction)buttonPressed:(id)sender;
② 重点介绍viewDidLoad,初始化方法:
- (void)viewDidLoad
{
[super viewDidLoad];
//Do any additional setup after loading the view from its nib.
NSBundle*bundle = [NSBundle mainBundle];
NSURL*plistURL = [bundle URLForResource:@"statedictionary" withExtension:@"plist"];
NSDictionary*dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
stateZips =dictionary;
NSArray*components = [stateZips allKeys];
NSArray*sorted = [components sortedArrayUsingSelector:@selector(compare:)];
states =sorted;
NSString*selectedState = [states objectAtIndex:0];
NSArray*array = [stateZips objectForKey:selectedState];
zips =array;
}
住:束的概念,字典文件初始化,数组排序;字典文件中值的查询;
③. 委托和数据源的函数实现,委托,多实现了一个方法
#pragma mark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView{
return 2;
}
- (NSInteger)pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component{
if(component== StateComponenet){
return [states count];
}
return [zips count];
}
#pragma mark Picker Delegate Methods
- (NSString*)pickerView:(UIPickerView*)pickerView titleForRow:(NSInteger)rowforComponent:(NSInteger)component{
if(component== StateComponenet){
return [states objectAtIndex:row];
}
return [zips objectAtIndex:row];
}
//这个方法只有选取器发生变化,就会调用这个方法;
- (void)pickerView:(UIPickerView*)pickerView didSelectRow:(NSInteger)rowinComponent:(NSInteger)component{
if(component== StateComponenet){
NSString*selectState = [states objectAtIndex:row];
NSArray *array= [stateZips objectForKey:selectState];
zips =array;
[picker selectRow:0 inComponent:ZipComponent animated:YES];
[picker reloadAllComponents];
}
}
- (CGFloat)pickerView:(UIPickerView*)pickerView widthForComponent:(NSInteger)component{
if(component== ZipComponent){
return 90;
}
return 200;
}
④ 束:是一种特定的文件夹类型,其中的内容遵循特定的结构,应用程序和框架都是束,[NSBundle mainBundle]此调用返回的束对象代表我们的应用程序;
⑤ - (void)pickerView:(UIPickerView*)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component只要选取器发生变化就会调用这个方法;
[picker selectRow:0 inComponent:ZipComponent animated:YES];//右侧组件设置为第一行
[picker reloadAllComponents];//重新加载所有的组件;
⑥ - (CGFloat)pickerView:(UIPickerView*)pickerView widthForComponent:(NSInteger)设置每个组件的宽度;
9. 自定义选取器创建简单的游戏
①编写头文件,实现五个数组,一个Label,一个button的响应,
②构建视图:
③实现旋转方法:
- (IBAction)spin{
BOOLwin = NO;
intnumInRow = 1;
intlastVal = -1;
for(int i=0;i< 5;i++){
intnewValue = random()%[self.colum1 count];
if(newValue== lastVal){
numInRow ++;
}
else{
numInRow =1;
}
lastVal = newValue;
[picker selectRow:newValueinComponent:i animated:YES];
[picker reloadComponent:i];
if(numInRow> 2){
win = YES;
}
}
④实现初始化方法;
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage*apple = [UIImage imageNamed:@"apple.png"];
UIImage*bar = [UIImage imageNamed:@"bar.png"];
UIImage*cherry = [UIImage imageNamed:@"cherry.png"];
UIImage*crown = [UIImage imageNamed:@"crown"];
UIImage*lemon = [UIImage imageNamed:@"lemon.png"];
UIImage*seven = [UIImage imageNamed:@"seven.png"];
for(int i=1; i<= 5;i++){
UIImageView*appleView = [[UIImageView alloc] initWithImage:apple];
UIImageView*barView = [[UIImageView alloc]initWithImage:bar];
UIImageView*cherryView = [[UIImageView alloc] initWithImage:cherry];
UIImageView *crownView = [[UIImageView alloc] initWithImage:crown];
UIImageView*lemonView = [[UIImageView alloc] initWithImage:lemon];
UIImageView*sevenView = [[UIImageView alloc]initWithImage:seven];
NSArray*imageViewArray = [[NSArray alloc]initWithObjects:appleView,barView,cherryView,crownView,lemonView,sevenView,nil];
NSString*fileName = [[NSString alloc]initWithFormat:@"colum%d",i];
[self setValue:imageViewArrayforKey:fileName];
}
//Do any additional setup after loading the view from its nib.
}
注意:self setValue:imageViewArrayforKey:fileName];为什么没有对数组直接进行初始化:
⑤ 委托实现:返回每个组件每行对应的视图;
- (UIView*)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)rowforComponent:(NSInteger)component reusingView:(UIView*)view{
NSString*arrayName = [[NSString alloc]initWithFormat:@"colum%d",component+1];
NSArray*array = [self valueForKey:arrayName];
return[array objectAtIndex:row];
}
10. 添加音乐效果和按钮的隐藏
① 添加两个方法
-(void)showButton{
button.hidden = NO;
}
- (void)playWinSound{
NSURL*soundURL = [[NSBundle mainBundle] URLForResource:@"win" withExtension:@"wav"];
SystemSoundIDsoundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(soundURL),&soundID);
AudioServicesPlaySystemSound(soundID);
label.text = @"Winning";
[self performSelector:@selector(showButton)withObject:nil afterDelay:1.5];//调用方法,还有延迟时间的设置;
}
②.在spin方法中加入:
button.hidden= YES;
NSString*path = [[NSBundle mainBundle] pathForResource:@"crunch" ofType:@"wav"];
SystemSoundIDsoundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)([NSURL fileURLWithPath:path]),&soundID);
AudioServicesPlaySystemSound(soundID);
if(win){
[self performSelector:@selector(playWinSound)withObject:nil afterDelay:0.5];
}else
{
[self performSelector:@selector(showButton)withObject:nil afterDelay:0.5];
}
三. 加AudioToolbox框架