您的位置:首页 > 产品设计 > UI/UE

UIPickView

2016-05-26 16:07 309 查看
目录

UIPickerView的使用(两个案例)

一、UIPickerView的使用

案例1:点菜系统



目标:

》使用UIPikcerView控件实现点菜系统

》掌握UIPikcerView的代理与数据源与代理方法的使用,与TableView类比

(1)UITableView的每一行Cell是在数据源里,而UIPikcerView的每一行View是在代理里

(2)UIPickerView每一行长什么样有两个方法

//-(NSString *)pickerView: titleForRow: forComponent:直接返回一个字符串
//-(UIView *)pickerView: viewForRow: forComponent: reusingView:直接返回一个view


#pragma mark - UIPickerViewDelegate methods
//数据部分的展示是交给代理来做
- (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;

》监听每组选中的行,更改Label数据
(1)使用代理方法(数据源改变但是pickview没有变化)
- (void)pickerView:didSelectRow:inComponent:

2)更改UIPickView选中的数据(让pickview跟随数据的改而改变)
[self.pickerView selectRow:randRow inComponent:i animated:YES];

》实现默认选中每一组的第一行数据
(1)在viewDidLoad方法调用【-(void)pickerView:didSelectRow:inComponent:】实现


》实现随机选菜单

(1)实现Label数据的随机变更

(2)实现pickerView的数据随机变更

(3)每一组对应行的数据一定要不同上一次的行数据

/**

*获取旧行与新行,使用while循环,

//旧行
NSInteger oldRow = [self.pickerView selectedRowInComponent:i];
//随机新行
NSInteger newRow = arc4random_uniform((int)rows);
//新行与旧行相同,再随机,直到不两只
while (newRow == oldRow) {
newRow = arc4random_uniform((int)rows);
}
*/

eg:
#pragma makr - 随机产生结果
- (IBAction)randNumber:(id)sender {
//1.获取列数
NSInteger colum = self.dataArray.count;

for (int i = 0; i < colum; i ++) {
//2.获取随机每列的随机行数
NSArray *items = self.dataArray[i];
unsigned int rowCount = (unsigned int)items.count;

unsigned int randRow = arc4random_uniform(rowCount);//arc4random_uniform指定范围,如果填arc4random_uniform(10),获取的数是0-9

//每列的随机行数不能与之前一样
// 获取旧的行数
NSInteger oldRow = [self.pickerView selectedRowInComponent:i];
while (oldRow == randRow) {
randRow = arc4random_uniform(rowCount);
}

// 0.0~0.9
//arc4random_uniform(10) * 0.1

// 0.00~0.99
//arc4random_uniform(100) * 0.01

//3.更改数据(数据源改变但是pickview没有变化)
[self pickerView:nil didSelectRow:randRow inComponent:i];
//更改UIPickView选中的数据
[self.pickerView selectRow:randRow inComponent:i animated:YES];

}
}


案例2.国旗选择

》掌握代理【-(UIView *)pickerView:viewForRow:forComponent:reusingView:】的使用



(1)在数据源里返回一组数据,行数由国旗个数决定

(2)在代理方法中使用上面的方法,每一行返回一个View,返回的这个view为label

(3)打印reusingView的地址和文字,”查看循环利用的view” –’备课的时候多演示几次’

//eg: NSLog(@”==%p %@”,label,label.text);

(4)使用一个xib描述国家和国旗

(5)掌握一个设置行高的代理方法

#pragma mark - 自定义pickerView行
//循环引用在ios7以后,不带明显,但是确实还是会循环引用
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{

//如果有重用的View,会传一个view进来,重用

FlagView *flagView = (FlagView *)view;
if (!flagView) {
flagView = [FlagView flageView];
}

#warning 一般设置自定义的view大小时,不直接设置bounds/frame
//自定义控件要添加bounds
flagView.bounds = CGRectMake(0, 0, 200, 0);

//设置数据
flagView.modelData = self.array[row];

//打印view的内存地址
NSLog(@"row = %ld,address: %p, name = %@",row, flagView,((FlagModel *)self.array[row]).name );

return flagView;
}
//设置高度无效,需要用代理设置高度

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

return 50;
}

//设置宽度
//- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
//    return 200;
//}


#import "FlagModel.h"

@interface FlagView : UIView

+ (instancetype)flageView;
@property (nonatomic, strong) FlagModel *modelData;

@end
#import "FlagView.h"

@interface FlagView ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end


@implementation FlagView

+ (instancetype)flageView{
//需要lastobject因为,xib中可以拖动多个视图,而且是同级的。
return  [[[NSBundle mainBundle] loadNibNamed:@"FlagView" owner:nil options:nil] lastObject];
}

- (void)setModelData:(FlagModel *)modelData{

_modelData = modelData;
self.label.text = modelData.name;
self.imageView.image = [UIImage imageNamed:modelData.icon];
}


案例3.省市联动



@property (nonatomic,assign)NSInteger indexOfProvice;//当前默认选中的省份


ViewController.m

// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 2;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
//第一列省份
if (component == 0) {//省分
return self.provinces.count;
}

//第二列:获取对应省份的城市个数
Province *province = self.provinces[self.indexOfProvice];

return province.cities.count;

}


#pragma mark 显示数据
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{

if(component == 0){//显示省份的名字
//对应列行的省份
Province *province = self.provinces[row];
return province.name;
}

//获取选中的城市,显示城市名字
Province *selectedProvice = self.provinces[self.indexOfProvice];
return selectedProvice.cities[row];
}

//方法二

//-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
//
//    UILabel *label = (UILabel *)view;
//    if (!label) {
//        label = [[UILabel alloc] init];
//    }
//
//    if(component == 0){//显示省份的名字
//        //对应列行的省份
//        Province *province = self.provinces[row];
//        label.text =  province.name;
//        label.backgroundColor = [UIColor grayColor];
//    }else{
//
//        //获取选中的城市,显示城市名字
//        Province *selectedProvice = self.provinces[self.indexOfProvice];
//        label.text = selectedProvice.cities[row];
//        label.backgroundColor = [UIColor blueColor];
//    }
//
//
//
//
//    return label;
//}


#pragma mark 选中行

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

if (component == 0) {//第一列省的选中改变后,就要更新第二列数据
//更新选中省份的索引
self.indexOfProvice = row;

//刷新数据
//全部刷新
//[pickerView reloadAllComponents];

//部份刷新
[pickerView reloadComponent:1];

//不管之前第二列选中第几行,重新刷新数据后,都显示每二列的第一行
[pickerView selectRow:0 inComponent:1 animated:YES];
}
}

#pragma mark 设置宽度
-(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
if (component == 0) {
return 80;
}

return 200;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  UIPickView