一、点菜系统练习(UIPickerView)
<1>UIPickerView的常用代理方法介绍
1 #pragma mark - <UIPickerViewDelegate> 2 3 // 返回指定列的行宽度 4 - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component 5 { 6 7 } 8 // 返回指定列中行的高度 9 - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component 10 { 11 12 } 13 14 // 返回第component列的第row行的字符串 15 - (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 16 { 17 18 } 19 // 富文本属性,可以描述文字的大小和颜色 20 - (nullable NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component 21 { 22 23 } 24 // 返回一个UIView 第component列第row行 25 - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view 26 { 27 28 } 29 // 人为选择第component列第row行之后执行的代码 30 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 31 { 32 33 }
<2>UIPickerView必须实现的两个数据源方法
1 #pragma mark - <UIPickerViewDataSource> 2 3 // 告诉pickView有多少列 4 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 5 { 6 return self.foods.count; 7 } 8 9 // 告诉pickView的component列中有多少行 10 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 11 { 12 return [self.foods[component] count]; 13 }
<3>练习代码
1 #import "ViewController.h" 2 3 @interface ViewController () <UIPickerViewDataSource,UIPickerViewDelegate> 4 @property (weak, nonatomic) IBOutlet UIPickerView *pickView; 5 /** 数据集合 */ 6 @property(nonatomic,strong) NSArray *foods; 7 @property (weak, nonatomic) IBOutlet UILabel *fruitLabel; 8 @property (weak, nonatomic) IBOutlet UILabel *mainLabel; 9 @property (weak, nonatomic) IBOutlet UILabel *drinkLabel; 10 11 @end 12 13 @implementation ViewController 14 15 - (void)viewDidLoad { 16 [super viewDidLoad]; 17 for (int i = 0; i < self.foods.count; i++) { 18 [self pickerView:self.pickView didSelectRow:0 inComponent:i]; 19 } 20 21 } 22 // 随机 23 - (IBAction)random:(id)sender { 24 for (int i = 0; i <self.foods.count; i++) { 25 int r = arc4random_uniform((int)[self.foods[i] count]); 26 [self.pickView selectRow:r inComponent:i animated:YES]; 27 [self pickerView:self.pickView didSelectRow:r inComponent:i]; 28 } 29 } 30 31 // 懒加载数据 32 - (NSArray *)foods 33 { 34 if (_foods == nil) { 35 NSString *path = [[NSBundle mainBundle] pathForResource:@"foods.plist" ofType:nil]; 36 _foods = [NSArray arrayWithContentsOfFile:path]; 37 } 38 return _foods; 39 } 40 41 #pragma mark - <UIPickerViewDataSource> 42 43 // 告诉pickView有多少列 44 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 45 { 46 return self.foods.count; 47 } 48 49 // 告诉pickView的component列中有多少行 50 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 51 { 52 return [self.foods[component] count]; 53 } 54 55 #pragma mark - <UIPickerViewDelegate> 56 57 // 返回指定列中行的高度 58 - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component 59 { 60 return 60; 61 } 62 63 // 返回第component列的第row行的字符串 64 - (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 65 { 66 return self.foods[component][row]; 67 } 68 69 // 人为选择第component列第row行之后执行的代码 70 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 71 { 72 switch (component) { 73 case 0: 74 self.fruitLabel.text = self.foods[component][row]; 75 break; 76 case 1: 77 self.mainLabel.text = self.foods[component][row]; 78 break; 79 case 2: 80 self.drinkLabel.text = self.foods[component][row]; 81 break; 82 } 83 } 84 85 @end
二、国旗选择练习(pickerView每行都是返回一个自定义控件)
1 // 2 // ViewController.m 3 // 0322国旗选择 4 // 5 // Created by admin on 16/3/22. 6 // Copyright © 2016年 admin. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "ChaosFlag.h" 11 #import "ChaosFlagView.h" 12 13 @interface ViewController () <UIPickerViewDataSource,UIPickerViewDelegate> 14 /** 数据模型集合 */ 15 @property(nonatomic,strong) NSMutableArray *flags; 16 @property (weak, nonatomic) IBOutlet UIPickerView *pickView; 17 18 @end 19 20 @implementation ViewController 21 22 - (void)viewDidLoad { 23 [super viewDidLoad]; 24 _pickView.delegate = self; 25 _pickView.dataSource = self; 26 } 27 - (NSMutableArray *)flags 28 { 29 if (_flags == nil) { 30 NSString *path = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil]; 31 NSArray *dicArray = [NSArray arrayWithContentsOfFile:path]; 32 NSMutableArray *arr = [NSMutableArray array]; 33 for (NSDictionary *dict in dicArray) { 34 ChaosFlag *flag = [ChaosFlag flagWithDict:dict]; 35 [arr addObject:flag]; 36 } 37 _flags = arr; 38 } 39 return _flags; 40 } 41 42 #pragma mark - <UIPickerViewDataSource> 43 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 44 { 45 return self.flags.count; 46 } 47 48 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 49 { 50 return 1; 51 } 52 53 #pragma mark - 代理方法 54 - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view 55 { 56 // 加载xib 57 ChaosFlagView *flagView = [[NSBundle mainBundle] loadNibNamed:@"ChaosFlagView" owner:nil options:nil][0]; 58 ChaosFlag *flag = self.flags[row]; 59 flagView.flag = flag; 60 return flagView; 61 } 62 - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component 63 { 64 return 70; 65 } 66 @end
三、生日选择,省市二级联动
1 // 2 // ViewController.m 3 // 0323-生日城市选择器 4 // 5 // Created by admin on 16/3/23. 6 // Copyright © 2016年 admin. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "ChaosProvince.h" 11 12 @interface ViewController () <UITextFieldDelegate,UIPickerViewDataSource,UIPickerViewDelegate> 13 @property (weak, nonatomic) IBOutlet UITextField *birthdayLabel; 14 @property (weak, nonatomic) IBOutlet UITextField *cityLabel; 15 16 /** 数据集合 */ 17 @property(nonatomic,strong) NSMutableArray *provinces; 18 19 /** datePicker */ 20 @property(nonatomic,strong) UIDatePicker *datePicker; 21 /** pickView */ 22 @property(nonatomic,strong) UIPickerView *pickView; 23 /** 选中的省会索引,用来保存上一次选择的省索引,防止同时拖拽省和市时报错 */ 24 @property(nonatomic,assign) NSInteger proIndex; 25 @end 26 27 @implementation ViewController 28 29 // 重写get方法,实现懒加载 30 - (NSMutableArray *)provinces 31 { 32 if (_provinces == nil) { 33 // 初始化数据模型,必须要实例化对象!国旗选择的练习中没有实例化,数据出不来,找了老半天! 34 _provinces = [NSMutableArray array]; 35 NSString *path = [[NSBundle mainBundle] pathForResource:@"provinces.plist" ofType:nil]; 36 NSArray *dicArray = [NSArray arrayWithContentsOfFile:path]; 37 for (NSDictionary *dict in dicArray) { 38 ChaosProvince *province = [ChaosProvince provinceWithDict:dict]; 39 [_provinces addObject:province]; 40 } 41 } 42 return _provinces; 43 } 44 45 - (void)viewDidLoad { 46 [super viewDidLoad]; 47 48 _cityLabel.delegate = self; 49 50 _birthdayLabel.delegate = self; 51 [self setBirthdayInputView]; 52 [self setCitiesInputView]; 53 } 54 /** 给文本框设置时间选择器的方法 */ 55 - (void)setBirthdayInputView 56 { 57 // 给生日文本框设置datePicker 58 _datePicker = [[UIDatePicker alloc] init]; 59 // 设置时间选择器的语言 zh--中国 60 _datePicker.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh"]; 61 // 设置时间选择器显示的时间格式 62 _datePicker.datePickerMode = UIDatePickerModeDate; 63 _birthdayLabel.inputView = _datePicker; 64 // 想要监听一个控件,没有delegate,就找addTarget方法(这个的前提是控件继承自UIControl) 65 [_datePicker addTarget:self action:@selector(dateChange:) forControlEvents:UIControlEventValueChanged]; 66 } 67 /** 监听时间选择器改变的方法 */ 68 - (void)dateChange:(UIDatePicker *)datePicker 69 { 70 // 取出时间 71 NSDate *date = datePicker.date; 72 // NSDate与NSString之间的转换 73 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 74 formatter.dateFormat =@"yyyy-MM-dd"; 75 NSString *time = [formatter stringFromDate:date]; 76 _birthdayLabel.text = time; 77 } 78 79 /** 给城市文本框设置选择器的方法 */ 80 - (void)setCitiesInputView 81 { 82 _pickView = [[UIPickerView alloc] init]; 83 _pickView.delegate = self; 84 _pickView.dataSource = self; 85 _cityLabel.inputView = _pickView; 86 } 87 88 #pragma mark - pickView数据源方法 89 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 90 { 91 if (component == 0) { // 省的个数 92 return self.provinces.count; 93 } else { // 省对应的城市 94 ChaosProvince *province = self.provinces[self.proIndex]; 95 return province.cities.count; 96 } 97 } 98 99 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 100 { 101 return 2; // 两列 102 } 103 104 #pragma mark - pickerView代理方法 105 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 106 { 107 if (component == 0) { // 省 108 ChaosProvince *province = self.provinces[row]; 109 return province.name; 110 } 111 else // 城市 112 { 113 // 根据省的索引获取对应的城市 114 ChaosProvince *province = self.provinces[self.proIndex]; 115 return province.cities[row]; 116 } 117 } 118 119 // 滚动pickerView就调用 120 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 121 { 122 if (component == 0) { // 选择省,刷新相应的城市 123 [pickerView reloadComponent:1]; 124 // 记录当前选中的省会索引 125 self.proIndex = [pickerView selectedRowInComponent:0]; 126 } 127 // 显示到文本框中 128 129 // 选中的省 130 ChaosProvince *province = self.provinces[self.proIndex]; 131 132 // 选中的城市 133 NSInteger cityIndex = [pickerView selectedRowInComponent:1]; 134 self.cityLabel.text = [NSString stringWithFormat:@"%@ %@",province.name,province.cities[cityIndex]]; 135 136 } 137 138 #pragma mark - <UITextFieldDelegate> 139 // 文本框开始编辑的时候执行的方法 140 - (void)textFieldDidBeginEditing:(UITextField *)textField 141 { 142 if (textField == self.birthdayLabel) { //生日文本 143 144 [self dateChange:_datePicker]; 145 } else if (textField == self.cityLabel) { // 城市文本 146 [self pickerView:self.pickView didSelectRow:0 inComponent:0]; 147 } 148 } 149 150 // 是否允许在范围内改变字符 151 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 152 { 153 return NO; 154 } 155 @end