返回

UIPickerView封装:提升代码的可读性和性能

IOS

在iOS实际项目中,经常会出现界面中多个地方需要使用UIPickerView,如果在每个需要用到的地方都创建一个UIPickerView不仅更耗性能,而且还会让你的代码变得更加杂乱、冗余,因此我在这里向大家介绍一下我对UIPickerView的一些简单封装。 如果只需要一列的话,可以使用这种方法,封装成一个自定义的控件,使用起来和 UITextField 一样简单:

@interface MyPickerView : UIView
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSArray *dataSource;
@property (nonatomic, copy) void(^didSelectItemBlock)(NSInteger row);
@end

然后在实现文件中添加以下代码:

@implementation MyPickerView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup
{
    UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:self.bounds];
    pickerView.delegate = self;
    pickerView.dataSource = self;
    [self addSubview:pickerView];
    
    // 设置标题
    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 30)];
    titleLabel.text = self.title;
    titleLabel.textAlignment = NSTextAlignmentCenter;
    [self addSubview:titleLabel];
}

// UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    return self.dataSource.count;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return self.dataSource[row];
}

// UIPickerViewDelegate
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    if (self.didSelectItemBlock) {
        self.didSelectItemBlock(row);
    }
}

@end

然后在使用的时候,只需要这样:

MyPickerView *pickerView = [[MyPickerView alloc] initWithFrame:CGRectMake(0, 100, 320, 216)];
pickerView.title = @"选择城市";
pickerView.dataSource = @[@"北京", @"上海", @"广州", @"深圳"];
pickerView.didSelectItemBlock = ^(NSInteger row) {
    NSLog(@"选择了第%ld行", row);
};
[self.view addSubview:pickerView];

当然,如果你需要多列的话,也可以使用这种方法进行封装,只需要在numberOfComponentsInPickerView方法中返回列数,在pickerView:titleForRow:forComponent:方法中返回对应列的数据源即可。