1.UIPickerView
作用:
- 从指定的数据源中选择数据
- 通常以UITextFiled的inputView出现,当选中的某个文本框时,弹出的键盘显示该控件
注意: - 使用pickerView之前需要指定数据源对象和代理对象
- 需要使用到两个协议:UIPickerViewDataSource数据源协议和UIPickerViewDelegate代理协议
plist文件
ViewController.m
#import "ViewController.h"
@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
//数据源数组
@property(nonatomic,strong)NSArray* foods;
//三个label控件
@property (weak, nonatomic) IBOutlet UILabel *fruits;
@property (weak, nonatomic) IBOutlet UILabel *vegetables;
@property (weak, nonatomic) IBOutlet UILabel *wine;
@property (weak, nonatomic) IBOutlet UIPickerView *pickView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置默认显示数据
/*
[self pickerView:self.pickView didSelectRow:0 inComponent:0];
[self pickerView:self.pickView didSelectRow:0 inComponent:1];
[self pickerView:self.pickView didSelectRow:0 inComponent:2];
*/
for (int i=0; i<self.foods.count; i++) {
[self pickerView:self.pickView didSelectRow:0 inComponent:i];
}
}
#pragma mark --------代理方法----------
//返回每个选项的内容
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return self.foods[component][row];
}
//选中某一行之后
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSString* selFood= self.foods[component][row];
switch (component) {
case 0:
self.fruits.text=selFood;
break;
case 1:
self.vegetables.text=selFood;
break;
case 2:
self.wine.text=selFood;
break;
default:
break;
}
}
#pragma mark --------数据源方法----------
//显示几组数据
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return self.foods.count;
}
//每组显示几条数据
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [self.foods[component] count];
}
#pragma mark --------懒加载数据----------
//重写foos的get方法
-(NSArray*)foods{
if (_foods==nil) {
//创建plist文件路径
NSString* path=[[NSBundle mainBundle]pathForResource:@"01foods.plist" ofType:nil];
//从pilist文件中读取数组
NSArray* foodCatageroy=[NSArray arrayWithContentsOfFile:path];
_foods=foodCatageroy;
}
return _foods;
}
@end
效果:
2.随机点餐
1、监听按钮的点击
2、让pickviewer随机选中数据
3、把数据显示在label上
#import "ViewController.h"
@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
//数据源数组
@property(nonatomic,strong)NSArray* foods;
//三个label控件
@property (weak, nonatomic) IBOutlet UILabel *fruits;
@property (weak, nonatomic) IBOutlet UILabel *vegetables;
@property (weak, nonatomic) IBOutlet UILabel *wine;
//拾取器
@property (weak, nonatomic) IBOutlet UIPickerView *pickView;
//随机点餐按钮
- (IBAction)btnRandomClick:(id)sender;
@end
@implementation ViewController
//点击随机点餐按钮
- (IBAction)btnRandomClick:(id)sender {
//遍历集合中的所有组
for (int i=0; i<self.foods.count; i++) {
//生成一个随机数去选中
u_int32_t count=arc4random_uniform((int)[self.foods[i] count]);
//让pickview选中数据
//将数据显示在label上
[self.pickView selectRow:count inComponent:i animated:YES];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
//设置默认显示数据
/*
[self pickerView:self.pickView didSelectRow:0 inComponent:0];
[self pickerView:self.pickView didSelectRow:0 inComponent:1];
[self pickerView:self.pickView didSelectRow:0 inComponent:2];
*/
for (int i=0; i<self.foods.count; i++) {
[self pickerView:self.pickView didSelectRow:0 inComponent:i];
}
}
#pragma mark --------代理方法----------
//返回每个选项的内容
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return self.foods[component][row];
}
//选中某一行之后
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSString* selFood= self.foods[component][row];
switch (component) {
case 0:
self.fruits.text=selFood;
break;
case 1:
self.vegetables.text=selFood;
break;
case 2:
self.wine.text=selFood;
break;
default:
break;
}
}
#pragma mark --------数据源方法----------
//显示几组数据
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return self.foods.count;
}
//每组显示几条数据
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [self.foods[component] count];
}
#pragma mark --------懒加载数据----------
//重写foos的get方法
-(NSArray*)foods{
if (_foods==nil) {
//创建plist文件路径
NSString* path=[[NSBundle mainBundle]pathForResource:@"01foods.plist" ofType:nil];
//从pilist文件中读取数组
NSArray* foodCatageroy=[NSArray arrayWithContentsOfFile:path];
_foods=foodCatageroy;
}
return _foods;
}
@end
3.随机点餐完善
#import "ViewController.h"
@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
//数据源数组
@property(nonatomic,strong)NSArray* foods;
//三个label控件
@property (weak, nonatomic) IBOutlet UILabel *fruits;
@property (weak, nonatomic) IBOutlet UILabel *vegetables;
@property (weak, nonatomic) IBOutlet UILabel *wine;
//拾取器
@property (weak, nonatomic) IBOutlet UIPickerView *pickView;
//随机点餐按钮
- (IBAction)btnRandomClick:(id)sender;
@end
@implementation ViewController
//点击随机点餐按钮
- (IBAction)btnRandomClick:(id)sender {
//遍历集合中的所有组
for (int i=0; i<self.foods.count; i++) {
//生成一个随机数去选中
u_int32_t count=arc4random_uniform((int)[self.foods[i] count]);
//获取第i组当前选中的行
NSInteger selectRowNumber=[self.pickView selectedRowInComponent:i];
while (count==selectRowNumber) {
count=arc4random_uniform((int)[self.foods[i] count]);
}
//让pickview选中数据
//将数据显示在label上
[self.pickView selectRow:count inComponent:i animated:YES];
//直接调用刚才自己写的显示文字的方法
[self pickerView:self.pickView didSelectRow:count inComponent:i];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
//设置默认显示数据
/*
[self pickerView:self.pickView didSelectRow:0 inComponent:0];
[self pickerView:self.pickView didSelectRow:0 inComponent:1];
[self pickerView:self.pickView didSelectRow:0 inComponent:2];
*/
for (int i=0; i<self.foods.count; i++) {
[self pickerView:self.pickView didSelectRow:0 inComponent:i];
}
}
#pragma mark --------代理方法----------
//返回每个选项的内容
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return self.foods[component][row];
}
//选中某一行之后,设置文字
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSString* selFood= self.foods[component][row];
switch (component) {
case 0:
self.fruits.text=selFood;
break;
case 1:
self.vegetables.text=selFood;
break;
case 2:
self.wine.text=selFood;
break;
default:
break;
}
}
#pragma mark --------数据源方法----------
//显示几组数据
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return self.foods.count;
}
//每组显示几条数据
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [self.foods[component] count];
}
#pragma mark --------懒加载数据----------
//重写foos的get方法
-(NSArray*)foods{
if (_foods==nil) {
//创建plist文件路径
NSString* path=[[NSBundle mainBundle]pathForResource:@"01foods.plist" ofType:nil];
//从pilist文件中读取数组
NSArray* foodCatageroy=[NSArray arrayWithContentsOfFile:path];
_foods=foodCatageroy;
}
return _foods;
}
@end
4.城市选择
1、plist文件
#import "ViewController.h"
#import "FRProvince.h"
@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
@property(nonatomic,strong)NSArray* provinces;
@property (weak, nonatomic) IBOutlet UIPickerView *pickView;
@property (weak, nonatomic) IBOutlet UILabel *lblProvince;
@property (weak, nonatomic) IBOutlet UILabel *lblCities;
//用来保存每次刷新后新选中的省
@property(nonatomic,strong) FRProvince* selectProvince;
@end
@implementation ViewController
#pragma mark -------代理方法----------
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
//如果选中的是第0组,则需要刷新城市书
if (component==0) {
[pickerView reloadComponent:1];
//去选中第1组城市第0行
[pickerView selectRow:0 inComponent:1 animated:YES];
}
//标签上显示文字内容
//获取省市索引
NSInteger selectProvinceIndex=[pickerView selectedRowInComponent:0];
NSInteger selectCityIndex=[pickerView selectedRowInComponent:1];
//从集合上取数据
FRProvince* selectProvice=self.provinces[selectProvinceIndex];
NSString* selectCityStr=self.selectProvince.cities[selectCityIndex];
self.lblProvince.text=selectProvice.name;
self.lblCities.text=selectCityStr;
}
//返回每一行显示的内容
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
//如果是第0组,返回模型的name属性
if (component==0) {
FRProvince* province= self.provinces[row];
return province.name;
}else{
// //第1组,根据省份数据,返回城市的数据
// NSInteger selectProvinceIndex=[pickerView selectedRowInComponent:0];
// FRProvince* selectProivince=self.provinces[selectProvinceIndex];
// return selectProivince.cities[row];
return self.selectProvince.cities[row];
}
}
#pragma mark -------数据源方法--------
//返回数据的组数
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 2;
}
//返回每组的行数
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
//如果是第0组, 省,行数就是模型数组数量
if (component==0) {
return self.provinces.count;
}else{
//如果是第1组,市 行数就是城市数组的数量
//获取第0组显示的是那个省
//先获取第0组选中的行号
NSInteger selectProvinceInx=[pickerView selectedRowInComponent:0];
//从集合中获取数据
FRProvince* province= self.provinces[selectProvinceInx];
//将新的省保留在self.selectProvince属性中
self.selectProvince=province;
//根据省的城市数据确定显示的城市的行数
return self.selectProvince.cities.count;
}
}
#pragma mark -------懒加载数据--------
//重写provinces属性
-(NSArray*)provinces{
if (_provinces==nil) {
//创建文件路径字符串
NSString* path=[[NSBundle mainBundle]pathForResource:@"02cities.plist" ofType:nil];
//从文件中得到数组
NSArray* arryDict=[NSArray arrayWithContentsOfFile:path];
//遍历数组并将数组中的字典添加到可变数组中
NSMutableArray* models=[NSMutableArray arrayWithCapacity:arryDict.count];//使用arradict的容量来创建可变数组
for (NSDictionary* dict in arryDict) {
FRProvince* model=[FRProvince provinceWithDictionary:dict];
[models addObject:model];
}
//将可变数组中写入到province属性中
_provinces=models;
}
//返回province属性
return _provinces;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
@end
效果
5.国别选择
1、plist文件
2、创建FRNation类
FRNation.h
#import <UIKit/UIKit.h>
#import "FRNation.h"
NS_ASSUME_NONNULL_BEGIN
@class FRNation;
@interface FRFlagView : UIView
@property(nonatomic,strong) FRNation* nation;
//绑定一个模型来设置数据
+(instancetype)flagView;
//封装一个view的高度的方法
+(CGFloat)rowHeight;
@end
NS_ASSUME_NONNULL_END
FRNation.m
#import "FRFlagView.h"
@interface FRFlagView()
@property (weak, nonatomic) IBOutlet UILabel *nationName;
@property (weak, nonatomic) IBOutlet UIImageView *nationFlag;
@end
@implementation FRFlagView
//重写nation的set方法
-(void)setNation:(FRNation *)nation{
_nation=nation;
self.nationName.text=nation.name;
self.nationFlag.image=[UIImage imageNamed:nation.icon];
}
//绑定一个模型来设置数据
+(instancetype)flagView{
FRFlagView* flagView=[[[NSBundle mainBundle]loadNibNamed:@"flag" owner:nil options:nil]lastObject];
return flagView;
}
//封装一个view的高度的方法
+(CGFloat)rowHeight{
return 80;
}
@end
3、创建xib文件,为pickView设定单元格
然后各种拖线,设定成员变量,并制定相应的类为FRFlagView
4、创建FRFlagView类
FRFlagView.h
#import <UIKit/UIKit.h>
#import "FRNation.h"
NS_ASSUME_NONNULL_BEGIN
@class FRNation;
@interface FRFlagView : UIView
@property(nonatomic,strong) FRNation* nation;
//绑定一个模型来设置数据
+(instancetype)flagView;
//封装一个view的高度的方法
+(CGFloat)rowHeight;
@end
NS_ASSUME_NONNULL_END
FRFlagView.m
#import "FRFlagView.h"
@interface FRFlagView()
@property (weak, nonatomic) IBOutlet UILabel *nationName;
@property (weak, nonatomic) IBOutlet UIImageView *nationFlag;
@end
@implementation FRFlagView
//重写nation的set方法
-(void)setNation:(FRNation *)nation{
_nation=nation;
self.nationName.text=nation.name;
self.nationFlag.image=[UIImage imageNamed:nation.icon];
}
//绑定一个模型来设置数据
+(instancetype)flagView{
FRFlagView* flagView=[[[NSBundle mainBundle]loadNibNamed:@"flag" owner:nil options:nil]lastObject];
return flagView;
}
//封装一个view的高度的方法
+(CGFloat)rowHeight{
return 80;
}
@end
5、ViewController类
#import "ViewController.h"
#import "FRNation.h"
#import "FRFlagView.h"
@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
@property(nonatomic,strong)NSArray* flags;
@property (weak, nonatomic) IBOutlet UIPickerView *pickView;
@end
@implementation ViewController
#pragma mark ------实现代理方法------
//返回每行标题(内容)
-(UIView*)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
//创建view
//加载xib文件
FRFlagView* flagView=[FRFlagView flagView];
//设置view的数据
flagView.nation=self.flags[row];
//设置view的frame
flagView.frame=CGRectMake(0, 0, self.view.bounds.size.width, [FRFlagView rowHeight]);
//返回view
return flagView;
}
//返回行高
-(CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
return [FRFlagView rowHeight];
}
#pragma mark ------数据源方法--------
//返回数据的组数
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
//返回每组的行数
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return self.flags.count;
}
#pragma mark ------懒加载数据--------
//重写flags的get方法
-(NSArray*)flags{
if (_flags==nil) {
//获取path路径
NSString* path=[[NSBundle mainBundle]pathForResource:@"03flags.plist" ofType:nil];
//获得所有字典的数组
NSArray* arrayDict=[NSArray arrayWithContentsOfFile:path];
//遍历数组并添加到可变模型数组
NSMutableArray* models=[NSMutableArray arrayWithCapacity:arrayDict.count];
for (NSDictionary* dict in arrayDict) {
FRNation* model=[FRNation nationWithDictionary:dict];
[models addObject:model];
}
_flags=models;
}
//返回flag属性
return _flags;
}
- (void)viewDidLoad {
[super viewDidLoad];
//self.pickView.
}
@end
效果:
6.UIDAtePicker日期选择控件
作用:
- 方便用户进行日期、时间的选择,并保证日期格式的正确
- 通常以UITextField的inputView的形式出现(一般不会单独放一个UIDatePickerView在界面上)
ps:
- 需要将UIDatePickerView设置为文本框的inputView
- 需要将UIToolBar设置为文本框的inputAccessoryView
datePicker和toolbar都可以使用懒加载的形式加载到界面上
代码如下:
#import "ViewController.h"
@interface ViewController ()
//文本框控件
@property (weak, nonatomic) IBOutlet UITextField *textField;
//日期选择控件
@property(nonatomic,strong) UIDatePicker* datePicker;
//工具条
@property(nonatomic,strong)UIToolbar* toolbar;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置文本框的输入界面为datePicker
self.textField.inputView=self.datePicker;
//设置文本框的输入界面为datePicker的toolbar
self.textField.inputAccessoryView=self.toolbar;
}
#pragma mark -------懒加载控件--------
//重写datePicker控件的get方法
-(UIDatePicker*)datePicker{
if (_datePicker==nil) {
//不需要设置frame,自动添加响应的frame
_datePicker=[[UIDatePicker alloc]init];
//日期模式
_datePicker.datePickerMode=UIDatePickerModeDate;
_datePicker.locale=[[NSLocale alloc]initWithLocaleIdentifier:@"zh-Hans"];
}
return _datePicker;
}
//重写toolbar控件的get方法
-(UIToolbar*)toolbar{
if (!_toolbar) {
_toolbar=[[UIToolbar alloc]init];
_toolbar.bounds=CGRectMake(0, 0, self.view.bounds.size.width, 40);
//创建按钮(UIBarButton)放在工具条里
//取消按钮
UIBarButtonItem* cancelItem=[[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(cancelItemClick)];
//中间的弹簧
UIBarButtonItem* flexSpace=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
//确认按钮
UIBarButtonItem* conformItem=[[UIBarButtonItem alloc] initWithTitle:@"确认" style:UIBarButtonItemStylePlain target:self action:@selector(conformItemClick)];
//添加以上的item,以数组元素的方式添加到toolbar上
_toolbar.items=@[cancelItem,flexSpace,conformItem];
}
return _toolbar;
}
//实现取消按钮上的方法
-(void)cancelItemClick{
[self.view endEditing:YES];
}
//实现确认按钮上的方法
-(void)conformItemClick{
//1、获取选中的日期
NSDate* date=self.datePicker.date;
//2、将日期设置给文本框
//将日期转为字符串
//创建一个日期转换器
NSDateFormatter* formatter=[[NSDateFormatter alloc]init];
//设置日期转换格式
formatter.dateFormat=@"yyyy年MM月dd日";
//将日期转换成字符串
NSString* dateStr=[formatter stringFromDate:date];
//正式转化
self.textField.text=dateStr;
//3、关闭键盘
[self.view endEditing:YES];
}
@end
效果如下: