UIPickerView的点滴

来源:互联网 发布:手机淘宝售后服务流程 编辑:程序博客网 时间:2024/05/16 13:16
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 的功能和用法。 


单列选择器 
  

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

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

接下来开始修改控制器类,本例打算使用控制器类作为UIPickerViewdataSourcedelegate,因此,程序需要让控制器类实现UIPickerViewDataSourceUIPickerViewDelegate两个协议。 
  

修改控制器类的实现代码,主要就是实现UIPickerViewDataSourceUIPickerViewDelegate两个协议中的必要方法,其代码如下。 
  


#import "ViewController.h"


@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>

@property (weak, nonatomic) IBOutlet UIPickerView *pickView;

@property (nonatomic, strong) NSArray *ary;

@property (nonatomic, strong) NSArray *songAry;

@end


@implementation ViewController

///懒加载

- (NSArray *)ary {

    if (!_ary) {

        self.ary = [NSArray arrayWithObjects:@"汪峰",@"小黄人",@"张学友",@"凤凰传奇",@"筷子兄弟",nil];

    }

    return _ary;

}



- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    

    self.pickView.dataSource = self;

    self.pickView.delegate = self;

    

}


#pragma mark---- UIPickerViewDataSource,


/// 返回的列数

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {

    return 1;

    

}


/// 每列返回的个数---列表数

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {

    

       return  self.ary.count;

    

}

#pragma mark---- UIPickerViewDelegate

/// 指定列和列表项的标题文本

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

{

   

        return _ary[row];

   

}

/// 选中列表中得选项触发

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

 

    UIAlertView *laert = [[UIAlertView alloc] initWithTitle:@"提示" message: [NSString stringWithFormat:@"选中的歌手%@",_ary[row],] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

    [laert show];

    

}

/// 返回指定列的宽度

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {

    

        return 90;

    

}


@end



上面的程序首先初始化了一个NSArray,接下来的关键就是实现了4个用粗体字表示的方法,其中有两个方法来自UIPickerViewDataSource协议,分别用于控制该UIPickerView控件包含多少列、各列包含多少个列表项;另两个方法则来自UIPickerViewDelegate,最后一个粗体字方法负责为UIPickerView控件的选中事件提供响应——当用户选中该UIPickerView的某个列表项时,系统将会自动激发该方法,该方法的实现逻辑就是使用UIAlertView显示用户选择的对象。


 多列选择器 

  对单列选择器而言,只要控制UIPickerViewdataSource对象的numberOfComponentsInPickerView:方法返回大于1的整数即可。

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

  接下来修改控制器类,本例打算使用控制器类作为UIPickerViewdataSourcedelegate,因此程序需要让控制器类实现UIPickerViewDataSourceUIPickerViewDelegate两个协议。 
  修改控制器类的实现代码,主要就是实现UIPickerViewDataSourceUIPickerViewDelegate两个协议中的必要方法,其代码如下。

#import "PickerViewController.h"


#define kCities @"cities"

#define kState @"state"


@interface PickerViewController () <UIPickerViewDataSource,UIPickerViewDelegate>

@property (nonatomic,retain) NSArray * arr;//接收数据;

@property (nonatomic,retain) NSArray * cityArr;//城市数据;

///省份

@property (nonatomic,retain) NSMutableArray * provinceArr;

@property (nonatomic,retain) UIPickerView * pickerView;


@end


@implementation PickerViewController

- (void)dealloc{

    [_arr release];

    [_cityArr release];

    [_provinceArr release];

    [_pickerView release];

    [super dealloc];

}


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    

    [self initData];

    

    self.pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0,100,375,200)];

    //显示内容;

    self.pickerView.showsSelectionIndicator = YES;

    //刷新某个滚轮的内容;

    //[self.pickerView reloadComponent:1];

    //获得选中滚轮当前所在行;

   // NSInteger row = [self.pickerView selectedRowInComponent:0];

    [self.view addSubview:self.pickerView];

    [_pickerView release];

    

    //指定代理;

    self.pickerView.delegate = self;

    self.pickerView.dataSource = self;

    

    UIButton * btn = [UIButton buttonWithType:UIButtonTypeSystem ];

    btn.frame = CGRectMake(100,400,175,40);

    btn.backgroundColor = [UIColor orangeColor];

    [btn addTarget:self action:@selector(handleBtn:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:btn];

    

}

//更新数据库;

- (void)initData{

    //获取索引;

    NSString * filePath = [[NSBundle mainBundle] pathForResource:@"city" ofType:@"plist"];

    //接收数据;

    self.arr = [NSArray arrayWithContentsOfFile:filePath];

    //获得省份的数据;

    self.provinceArr = [NSMutableArray arrayWithCapacity:1];

    for (NSDictionary * dic in _arr) {

        //获取省份的信息;

        NSString * province = dic[kState];

        [self.provinceArr addObject:province];

       

    }

    //默认显示第一个省得内容;

    self.cityArr = self.arr[0][kCities];

    

}



- (void)handleBtn:(UIButton *)sender{

  

}


#pragma mark -- UIPickerView DataSource;

//返回滚轮的个数

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{

    return 2;


}


//返回每个滚轮的行数;

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{

    return (0 == component) ? self.provinceArr.count : self.cityArr.count;

}

#pragma mark -- UIPickerView Delegate

//设置每一行的内容;

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

    return (0 == component) ? self.provinceArr[row] : self.cityArr[row];


}


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

    if (0 == component) {

        //获取第一个滚轮操作的行

        NSInteger row = [self.pickerView selectedRowInComponent:0];

        //获取市区的数据;

        self.cityArr = self.arr[row][kCities];

        //更新第二个滚轮的信息;

        [self.pickerView reloadComponent:1];

        //每次滚动时,让第二个滚轮选中第一行的内容;

        [self.pickerView selectRow:0 inComponent:1 animated:YES];

    }

}



  

                                



下面是看别人的 一个游戏的实现 -----以供参考

 相互依赖的多列选择器


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


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


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


  接下来开始修改控制器类,本例使用控制器类作为UIPickerViewdataSourcedelegate,因此,程序需要让控制器类实现UIPickerViewDataSourceUIPickerViewDelegate两个协议。


  修改控制器类的实现代码,主要就是实现UIPickerViewDataSourceUIPickerViewDelegate两个协议中的必要方法,其代码如下。


  
复制代码
  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.   [NSArrayarrayWithObjects:@\\\\\\\\\\\\\\\"飞鸟集\\\\\\\\\\\\\\\", @\\\\\\\\\\\\\\\"吉檀迦利\\\\\\\\\\\\\\\", nil]
  12.   , @\\\\\\\\\\\\\\\"泰戈尔\\\\\\\\\\\\\\\",
  13.   [NSArrayarrayWithObjects:@\\\\\\\\\\\\\\\"醒世恒言\\\\\\\\\\\\\\\",@\\\\\\\\\\\\\\\"喻世明言\\\\\\\\\\\\\\\"
  14.   , @\\\\\\\\\\\\\\\"警世通言\\\\\\\\\\\\\\\", nil] , @\\\\\\\\\\\\\\\"冯梦龙\\\\\\\\\\\\\\\",
  15.   [NSArrayarrayWithObjects:@\\\\\\\\\\\\\\\"疯狂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 [[booksobjectForKey: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 [[booksobjectForKey: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允许开发者对列表项进行任意定制。开发者只要实现UIPickerViewDelegate协议中的-pickerView:viewForRow:forComponent: reusingView:方法即可,该方法返回的UIView将作为UIPickerView指定列和列表项的视图控件。


  实例:“老虎机”游戏


  下面以一个简单的“老虎机”游戏实例来示范自定义选择器视图的用法。


  首先创建一个Single View Application,使用Interface Builder打开应用的界面设计文件,并将一个UIPickerView拖入界面设计文件中,再将一个UIImageView和一个UIButton拖入应用界面中,然后将这三个控件摆放整齐。为了在程序中访问这三个控件,分别将它们绑定到pickerimagestartBn这三个IBAction属性。除此之外,程序还需要响应按钮的点击事件,因此为该按钮控件的Touch Up Inside事件绑定clicked:事件处理方法。




  提示:


  “老虎机”游戏的列表项都是图标,则需要为该实例准备一些图标——读者既可用本实例提供的图标,也可用自己选择的图标,但图标不要太大,以小于60像素×60像素为宜,将这些图标拖入应用中即可。


   
  接下来开始修改控制器类,本例使用控制器类作为UIPickerViewdataSourcedelegate,因此程序需要让控制器类实现UIPickerViewDataSourceUIPickerViewDelegate两个协议。除此之外,程序需要分别为UIPickerView5列准备数据,因此程序在控制器类的接口部分定义了5NSArray属性,其代码如下。


  程序清单:codes/10/10.12/CustomPicker/CustomPicker/FKViewController.h


复制代码
  1.    @interface FKViewController : UIViewController
  2. <UIPickerViewDataSource,UIPickerViewDelegate>
  3. // 分别绑定到应用界面的三个UI控件
  4. @property (strong, nonatomic) IBOutlet UIPickerView*picker;
  5. @property (strong, nonatomic) IBOutlet UIImageView*image;
  6. @property (strong, nonatomic) IBOutlet UIButton*startBn;
  7. - (IBAction)clicked:(id)sender;
  8. @end


然后修改该控制器类的实现部分,主要就是实现UIPickerViewDataSourceUIPickerViewDelegate两个协议中的必要方法,其代码如下。


复制代码
  1.    @implementation FKViewController
  2. UIImage* loseImage;
  3. UIImage* winImage;
  4. // 保存系统中所有图片的集合
  5. NSArray* images;
  6. - (void)viewDidLoad
  7. {
  8. [superviewDidLoad];
  9. loseImage= [UIImage imageNamed:@\\\\\\\\\\\\\\\"lose.jpg\\\\\\\\\\\\\\\"];
  10. winImage =[UIImage imageNamed:@\\\\\\\\\\\\\\\"win.gif\\\\\\\\\\\\\\\"];
  11. // 依次加载6张图片,生成对应的UIImage对象
  12. UIImage*dog = [UIImage imageNamed:@\\\\\\\\\\\\\\\"dog.png\\\\\\\\\\\\\\\"];
  13. UIImage*duck = [UIImage imageNamed:@\\\\\\\\\\\\\\\"duck.png\\\\\\\\\\\\\\\"];
  14. UIImage*elephant = [UIImage imageNamed:@\\\\\\\\\\\\\\\"elephant.png\\\\\\\\\\\\\\\"];
  15. UIImage*frog = [UIImage imageNamed:@\\\\\\\\\\\\\\\"frog.png\\\\\\\\\\\\\\\"];
  16. UIImage*mouse = [UIImage imageNamed:@\\\\\\\\\\\\\\\"mouse.png\\\\\\\\\\\\\\\"];
  17. UIImage*rabbit = [UIImage imageNamed:@\\\\\\\\\\\\\\\"rabbit.png\\\\\\\\\\\\\\\"];
  18. // 初始化images集合,将前面的6张图片封装成images集合
  19. images =[NSArray arrayWithObjects: dog, duck, elephant,
  20. frog,mouse, rabbit,nil];
  21. self.picker.dataSource= self;
  22. self.picker.delegate= self;
  23. }
  24. // UIPickerViewDataSource中定义的方法,该方法的返回值决定该控件包含多少列
  25. -(NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView
  26. {
  27. // 返回5表明该控件只包含5列
  28. return 5;
  29. }
  30. // UIPickerViewDataSource中定义的方法,该方法的返回值决定该控件指定列包含多少个列表项
  31. - (NSInteger)pickerView:(UIPickerView *)pickerView
  32. numberOfRowsInComponent:(NSInteger)component
  33. {
  34. // images集合包含多少个元素,该控件的各列就包含多少个列表项
  35. return images.count;
  36. }
  37. #define kImageTag 1
  38. // UIPickerViewDelegate中定义的方法,该方法返回的UIView将作为
  39. // UIPickerView中指定列和列表项的UI控件
  40. - (UIView*)pickerView:(UIPickerView *)pickerView viewForRow:
  41. (NSInteger)rowforComponent:(NSInteger)component
  42. reusingView:(UIView *)view
  43. {
  44. // 如果可重用的view的tag不等于kImageTag,表明该view已经不存在,需要重新创建
  45. if(view.tag != kImageTag)
  46. {
  47. view = [[UIImageView alloc]initWithImage:[images objectAtIndex:row]];
  48. // 为该UIView设置tag属性
  49. view.tag = kImageTag;
  50. // 设置不允许用户交互
  51. view.userInteractionEnabled = NO;
  52. }
  53. return view;
  54. }
  55. //UIPickerViewDelegate中定义的方法,该方法的返回值决定列表项的高度
  56. -(CGFloat)pickerView:(UIPickerView *)pickerView
  57. rowHeightForComponent:(NSInteger)component
  58. {
  59. return 40;
  60. }
  61. //UIPickerViewDelegate中定义的方法,该方法的返回值决定列表项的宽度
  62. -(CGFloat)pickerView:(UIPickerView *)pickerView
  63. widthForComponent:(NSInteger)component
  64. {
  65. return 40;
  66. }
  67. - (IBAction)clicked:(id)sender {
  68. self.startBn.enabled= NO; // 禁用该按钮
  69. self.image.image= nil; // 清空界面上image控件中的图片
  70. // 定义一个NSMutableDictionary来记录每个随机数的出现次数
  71. NSMutableDictionary*result = [[NSMutableDictionary alloc]
  72. initWithCapacity:6];
  73. NSURL*winSoundUrl = [[NSBundle mainBundle]
  74. URLForResource:@\\\\\\\\\\\\\\\"crunch\\\\\\\\\\\\\\\"withExtension:@\\\\\\\\\\\\\\\"wav\\\\\\\\\\\\\\\"];
  75. SystemSoundIDsoundId;
  76. // 装载声音文件
  77. AudioServicesCreateSystemSoundID((__bridgeCFURLRef)
  78. (winSoundUrl),&soundId);
  79. // 播放声音
  80. AudioServicesPlaySystemSound(soundId);
  81. for(int i= 0 ; i < 5 ; i++)
  82. {
  83. // 生成0~images.count之间的一个随机数
  84. NSUInteger selectedVal = arc4random() %images.count;
  85. [self.picker selectRow:selectedValinComponent:i animated:YES];
  86. // 在result中已经为该随机数记录了出现次数
  87. if([resultobjectForKey:[NSNumber numberWithInt:selectedVal]])
  88. {
  89. //获取result中该随机数的出现次数
  90. NSUIntegernewCount = [[result objectForKey:
  91. [NSNumbernumberWithInt:selectedVal]] integerValue];
  92. //将result中该随机数的出现次数+1
  93. [resultsetObject:[NSNumber numberWithInt:(newCount + 1)]
  94. forKey:[NSNumbernumberWithInt:selectedVal]];
  95. }
  96. else
  97. {
  98. //使用result记录该随机数的出现次数为1
  99. [resultsetObject:[NSNumber numberWithInt:1]
  100. forKey:[NSNumbernumberWithInt:selectedVal]];
  101. }
  102. // 使用该变量记录随机数的最大出现次数
  103. NSUIntegermaxOccurs = 1;
  104. for(NSNumber* num in [result allKeys])
  105. {
  106. //只要任何随机数的出现次数大于maxOccurs
  107. if([[result objectForKey:num] integerValue] > maxOccurs)
  108. {
  109. //使用maxOccurs保存该随机数的出现次数
  110. maxOccurs= [[result objectForKey:num] integerValue];
  111. }
  112. }
  113. // 如果某个随机数的出现次数大于或等于3(即使界面出现了3个相同的图案)
  114. if(maxOccurs>= 3)
  115. {
  116. //如果赢了,延迟0.5秒执行showWin方法,显示结果
  117. [selfperformSelector:@selector(showWin)
  118. withObject:nilafterDelay:0.5];
  119. }
  120. else
  121. {
  122. //如果输了,延迟0.5秒执行showLose方法,显示结果
  123. [selfperformSelector:@selector(showLose)
  124. withObject:nilafterDelay:0.5];
  125. }
  126. }
  127. }
  128. - (void) showWin
  129. {
  130. NSURL*winSoundUrl = [[NSBundle mainBundle]
  131. URLForResource:@\\\\\\\\\\\\\\\"win\\\\\\\\\\\\\\\"withExtension:@\\\\\\\\\\\\\\\"wav\\\\\\\\\\\\\\\"];
  132. SystemSoundIDsoundId;
  133. // 装载声音文件
  134. AudioServicesCreateSystemSoundID((__bridgeCFURLRef)
  135. (winSoundUrl),&soundId);
  136. // 播放声音
  137. AudioServicesPlaySystemSound(soundId);
  138. self.image.image= winImage;
  139. self.startBn.enabled= YES;
  140. }
  141. - (void) showLose
  142. {
  143. self.image.image= loseImage;
  144. self.startBn.enabled= YES;
  145. }
  146. @end




上面程序中为UIPickerView实现自定义列表项的关键就是第一段粗体字代码,该方法返回一个UIImageView作为各列的列表项控件。因此,该示例中UIPickerView所包含的各列的列表项都是UIImageView控件。


  接下来的两行粗体字代码负责生成一个随机数,并根据生成的随机数来选中UIPickerView的指定列表项,这样就可让UIPickerView5列随机选中指定的列表项——程序接下来的代码判断5个随机数中是否有相同的数出现过3次以上(意味着UIPickerView5列中出现了3个以上相同的图标)——如果符合该条件,程序就延迟0.5秒执行showWin方法(该方法就是播放胜利音乐并显示胜利图标),否则就延迟0.5秒执行showLose方法(该方法显示失败图标)。


  由于该程序使用AudioToolbox来播放音乐,因此程序还需要将win.wavcrunch.wav两个音乐文件拖入项目中。除此之外,iOS项目默认是不带AudioToolbox库的,因此需要手动添加AudioToolbox库,为iOS项目添加指定库的步骤如下。


  ① 在项目导航面板中单击指定项目对应的图标。


  ② 选中中间编辑区域左侧的TARGETS下面的应用,如图10.50所示。


  
   10.50 添加库 
  
  

③ 选择编辑窗口上方的Build Phases标签,单击Link Binary With Libraries旁边的三角符号,即可展开该项目当前包含的所有库,如图10.51所示。 




   10.50 添加库 

   
  

④ 单击图10.51所示窗口中“添加库”的“+”图标,系统将会显示如图10.52所示的库列表。 
  

⑤ 在图10.52所示的对话框中选中需要添加的库(也可通过上面的搜索框进行搜索),单击“Add”按钮即可完成添加。 




  

10.52  选择需要添加的库  
  
  

按上面所示步骤为该项目添加AudioToolbox库,然后编译、运行该程序,即可通过单击程序界面上的按钮开始游戏,游戏界面如图10.53所示。 
  



  

10.53  自定义UIPickerView实现老虎机 
  
0 0
原创粉丝点击