[IOS]今天开始学UI---UIPickerView

本文介绍了UIPickerView与UIDatePickerView的区别,指出UIDatePickerView是独立于UIPickerView的组件。内容详细讲解了UIPickerView的构成、添加到视图的条件、需要遵循的UIPickerViewDataSource和UIPickerViewDelegate协议,以及如何实现滚轮的选择与显示效果。通过示例代码展示了如何创建并定制UIPickerView,最终更新UILabel内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UIPickerView和UIDatePickerView很类似

也许你会想UIDatePickerView是继承自UIPickerView

但是并非如此UIDatePickerView持有UIPickerView 并对其进行了一些个性化


UIPickerView的效果如下图


由若干个滚轮组成(numberOfRowsInComponent),每个滚轮都有一些列的条目

便于选择复合选项


要在当前的View中添加UIPickerView则需要遵循其UIPickerViewDataSource, UIPickerViewDelegate两项协议

UIPickerViewDataSource 负责的是构建一个UIPickerView的最基本信息 数据源 (比如多少个滚轮,每个滚轮多少行)

UIPickerViewDelegate 负责的则是UIPickerView视图效果 一些行为操作代理 (比如滚轮的宽度,滚轮上显示的字,是否选中某值)


构建一个UIPickerView需要遵从的最基础协议定义在UIPickerViewDateSource 主要有两个方法需要实现:

@protocol UIPickerViewDataSource<NSObject>
@required

// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;

// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
@end

第一个返回多少个滚轮组建,第二个怎时返回每个组建上有多少行


当以上两个方法实现后如果 没有实现UIPickerViewDelegate中的某些个方法 你看的效果嗯 大概就是没有加特技那样

你可以选择性的实现以下中的方法一个

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component 
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;
分别是提供一般的字符,属性字,或者自定义view 到滚轮中的某个row

让他们看起来比较的cooooool


所以代码如下

@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
@property (nonatomic,strong) UIPickerView *pickerView;
@property (nonatomic,strong) NSArray *singers;
@property (nonatomic,strong) NSArray *songs;
@property (nonatomic,strong) NSDictionary *dic;
@property (nonatomic,strong) UILabel *currentSelected;
@end
实现两个协议,并持有两个数组用来存放第一个滚轮显示的字符串singers songs dic 则是维系singers 和songs 关系  currentSelected显示当前所选择情况


- (void)viewDidLoad {
    [super viewDidLoad];
    //init source data
    NSString *path=[[NSBundle mainBundle] pathForResource:@"Songs" ofType:@"plist"];
    _dic = [NSDictionary dictionaryWithContentsOfFile:path];
    _singers = [_dic allKeys];
    NSInteger selectedSingerIndex = [self.pickerView selectedRowInComponent:0];
    NSString *selectedSinger = [_singers objectAtIndex:selectedSingerIndex];
    _songs = [_dic objectForKey:selectedSinger];
    _pickerView = [[UIPickerView alloc] init];
    _pickerView.center = self.view.center;
    _pickerView.dataSource = self;
    _pickerView.delegate = self;
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:_pickerView];
    _currentSelected = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 50)];
    _currentSelected.center = CGPointMake(self.view.center.x, self.view.center.y-200);
    [_currentSelected setText:[NSString stringWithFormat:@"%@  %@",[_singers objectAtIndex:0],[_songs objectAtIndex:0]]];
    [_currentSelected setTextAlignment:NSTextAlignmentCenter];
    [self.view addSubview:_currentSelected];


}


初始化数据源 UIPikcerView当前的选中状态

必要实现部分

#pragma mark required method
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    if (component == 0) {
        return  [_singers count];
    }else{
        return [_songs count];
    }
}

共2个滚轮组建 每个组分别有 [_singers count] 和[_songs count] 行

这里滚轮的组建是有编号的 从0开始 每多一个滚轮组建就+1 

当构建UIPickerView的Row视图时 传入当前组建滚轮的编号 然后得到该组建的Row 的个数 所以需要判断component是多少



#pragma mark optional method
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    if (component == 0) {
        NSString* selectedSinger=[_singers  objectAtIndex:row];
        NSArray* array=[_dic objectForKey:selectedSinger];
        _songs=array;
        //选择指定的item
        [self.pickerView selectRow:0 inComponent:1 animated:YES];
        //刷新指定列中的行
        [self.pickerView reloadComponent:1];

    }
    [self updateLabel:pickerView];
}

-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
    if (component == 0) {
        return  [_singers objectAtIndex:row];
    }else {
        return [_songs objectAtIndex:row];
    }
}
#pragma mark self-defined method
-(void)updateLabel:(UIPickerView *)pickerView{
    NSInteger singerRow=[pickerView selectedRowInComponent:0];
    NSInteger songRow=[pickerView selectedRowInComponent:1];
    NSString* selectedSinger=[_singers objectAtIndex:singerRow];
    NSString* selectedSong=[_songs objectAtIndex:songRow];
    [_currentSelected setText:[NSString stringWithFormat:@"%@  %@",selectedSinger,selectedSong]];
}


这里我们需要根据滚轮0 的选择 来刷新 滚轮 1的状态

而选择滚轮1 的时候不刷新任何状态,所以在

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

仅判断滚轮是否为0

同时刷新数据源 和选择状态


最后调用自定义方法 更新UILabel显示的内容






that's all

thx


Everything you see on Screen is UIView.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值