iOS-UIPickerView详解

https://www.jianshu.com/p/81cd9978c97c

iOS-UIPickerView详解

// pickView初始化并设置其大小,如果不设置其大小,默认大小为 320 * 216。

UIPickerView *pickView = [[UIPickerView alloc]initWithFrame:self.view.frame];

// 显示选中指示器,有一个透明的覆盖在选中航,默认是NO,iOS7 之后总是显示选中指示器,设置这个属性没有影响。

pickView.showsSelectionIndicator = YES;

//在iOS 7之后可以自定义选择器视图的背景颜色改变其backgroundColor

pickView.backgroundColor = [UIColor grayColor];

//设置pickVIew的透明度

pickView.alpha = 0.7;

//获取pickView的列数,只读属性

pickView.numberOfComponents;

//获取某一列的行数

NSInteger rowNum = [pickView numberOfRowsInComponent:0];

//获取某一列行的Size

CGSize rowSize = [pickView rowSizeForComponent:0];

//返回第component列,第row行的控件。
//一般用代理的pickerView:viewForRow:forComponent:reusingView:方法。

UIView *view = [pickView viewForRow:0 forComponent:0];

// 更新某一列 和 更新全部

[pickView reloadComponent:0];
[pickView reloadAllComponents];

//动画效果跳到选中某一列的某一行

[pickView selectRow:0 inComponent:0 animated:YES];

//返回某一列的选中行,-1表示没有选中行

[pickView selectedRowInComponent:0];  

UIPickerView的代理方法

UIPickerView的代理方法有两个UIPickerViewDelegate和UIPickerViewDataSource

UIPickerViewDataSource 数据源代理方法设置UIPickerView的行数与列数。

@protocol UIPickerViewDataSource<NSObject>
@required

// 返回多少列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;

// 返回每列的行数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
@end

!以上这两个方法是代理必须实现的。

UIPickerViewDelegate代理方法设置UIPickerView的内容。

@protocol UIPickerViewDelegate<NSObject>@optional

// 反回pickerView的宽度
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component __TVOS_PROHIBITED;

// 返回pickerView的高度
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component __TVOS_PROHIBITED;
  
// 返回pickerView 每行的内容
- (nullableNSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component __TVOS_PROHIBITED;

- (nullable NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component 

// 返回pickerView 每行的view 
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullableUIView *)view __TVOS_PROHIBITED;

// 选中行
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component __TVOS_PROHIBITED;
@end

!以上方法为选择实现

了解这些以后 我们做一个简单的UIPickerView 就不成问题了

//
//  ViewController.m
//  01-点菜系统
#import "ViewController.h"

@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>

@property(nonatomic , strong)NSArray *foodsData;
@property (weak, nonatomic) IBOutlet UILabel *fruitLabel;
@property (weak, nonatomic) IBOutlet UILabel *mainFoodLabel;
@property (weak, nonatomic) IBOutlet UILabel *drinkLabel;

@property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
@end

@implementation ViewController

// 数据数组的懒加载
-(NSArray *)foodsData
{
    if (_foodsData == nil) {
        _foodsData = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"foods.plist" ofType:nil]];
    }
    return _foodsData;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.fruitLabel.text = self.foodsData[0][0];
    self.mainFoodLabel.text = self.foodsData[1][0];
    self.drinkLabel.text = self.foodsData[2][0];
    
}

#pragma mark UIPickerViewDataSource 数据源方法
// 返回多少列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return self.foodsData.count;
    
}

// 返回多少行
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    NSArray *items = self.foodsData[component];
    return items.count;
    
}

#pragma mark UIPickerViewDelegate 代理方法

// 返回每行的标题
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return self.foodsData[component][row];
}
// 选中行显示在label上
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    NSArray *items = self.foodsData[component];
    if (component == 0) {
        self.fruitLabel.text = items[row];
    }else if (component == 1){
        self.mainFoodLabel.text = items[row];
    }else{
        self.drinkLabel.text = items[row];
    }
}
// 随机按钮点击事件
- (IBAction)randomNumber {
    int com = (int)self.foodsData.count;
    
    for (int i = 0; i < com; i++) {
        int oldrow = (int)[self.pickerView selectedRowInComponent:i];
        
        NSArray *items = self.foodsData[i];
        
        int num = (int)items.count;
        
        int randomNum = oldrow;
        
        while (oldrow == randomNum) {
            randomNum = arc4random() %num;
        }
        [self.pickerView selectRow:randomNum inComponent:i animated:YES];
        [self pickerView:self.pickerView didSelectRow:randomNum inComponent:i];
    }
    
}
@end



作者:xx_cc
链接:https://www.jianshu.com/p/81cd9978c97c
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
 
 
 

//

//  AdressPickVC.m

//  AutoOwnerTV

//

//  Created by admin on 2018/8/25.

//  Copyright © 2018年 autoTV. All rights reserved.

//

 

#import "AdressPickVC.h"

#import "AddressPickerModel.h"

#import "StrUtil.h"

 

@interface AdressPickVC ()<UIPickerViewDelegate, UIPickerViewDataSource>

@property (weak, nonatomic) IBOutlet UIView *vtitle;

@property (weak, nonatomic) IBOutlet UIButton *btnClose;

@property (weak, nonatomic) IBOutlet UIPickerView *pickerView;

@property (nonatomic, strong) NSArray <AddressPickerModel*>*dataSource;

@property (nonatomic, strong) NSArray <CityModel *> *dsCitys;

@property (nonatomic, strong) NSArray <AreaModel *> *dsAreas;

@property (nonatomic, strong) NSArray <StreetModel *> *dsStreets;

 

@property (nonatomic, assign) NSInteger proviceIndex;

@property (nonatomic, assign) NSInteger cityIndex;

@property (nonatomic, assign) NSInteger areaIndex;

@property (nonatomic, assign) NSInteger streetIndex;

 

@property (nonatomic, copy) NSString *sprovice;

@property (nonatomic, copy) NSString *scity;

@property (nonatomic, copy) NSString *sarea;

@property (nonatomic, copy) NSString *sstreet;

@end

 

@implementation AdressPickVC

 

- (void)viewDidLoad {

    [super viewDidLoad];

    self.proviceIndex = 0;

    self.cityIndex = 0;

    self.areaIndex = 0;

    self.streetIndex = 0;

    [self setSubV];

    [self requestData];

}

- (void)setSubV{

    self.view.userInteractionEnabled = YES;

    self.vtitle.userInteractionEnabled = YES;

    self.pickerView.userInteractionEnabled = YES;

    self.pickerView.delegate = self;

    self.pickerView.dataSource = self;

    //

    [_btnClose addTarget:self action:@selector(dismissVC) forControlEvents:UIControlEventTouchUpInside];

}

- (void)dismissVC{

    [self dismissViewControllerAnimated:YES completion:nil];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

#pragma mark 数据源初始化

- (NSArray<AddressPickerModel *> *)dataSource{

    if (!_dataSource) {

        _dataSource = [[NSArray alloc] init];

    }

    return _dataSource;

}

- (NSArray<CityModel *> *)dsCitys{

    if (!_dsCitys) {

        _dsCitys = [[NSArray alloc] init];

    }

    return _dsCitys;

}

- (NSArray<AreaModel *> *)dsAreas{

    if (!_dsAreas) {

        _dsAreas = [[NSArray alloc] init];

    }

    return _dsAreas;

}

- (NSArray<StreetModel *> *)dsStreets{

    if (!_dsStreets) {

        _dsStreets = [[NSArray alloc] init];

    }

    return _dsStreets;

}

#pragma mark 读取数据

- (void)requestData{

    NSData *data = [NSData dataNamed:@"address.json"];

    NSError *error;

    NSArray *arrayTemp = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

    NSMutableArray <AddressPickerModel *>*mproviceArrayModel = [[NSMutableArray alloc] init];

    for (NSDictionary *proviceDict in arrayTemp) {

        

        AddressPickerModel *addrPickerModel = [[AddressPickerModel alloc] init];

        addrPickerModel.province = proviceDict[@"string"];

        

        NSArray *arrdicCity = proviceDict[@"array"];

        NSMutableArray <CityModel *>*mcityArrayModel = [[NSMutableArray alloc] init];

        for (NSDictionary *dicCity in arrdicCity) {

            CityModel *cityModel = [[CityModel alloc] init];

            cityModel.city = dicCity[@"string"];

            NSArray *arrdicArea = dicCity[@"array"];

            NSMutableArray <AreaModel *>*mareaArrayModel = [[NSMutableArray alloc] init];

            for (NSDictionary *dicArea in arrdicArea) {

                AreaModel *areaModel = [[AreaModel alloc] init];

                areaModel.area = dicArea[@"string"];

                NSArray *arrdicStreet = dicArea[@"streets"];

                NSMutableArray <StreetModel *> *mstreetArrayModel = [[NSMutableArray alloc] init];

                for (NSString *strstreet in arrdicStreet) {

                    StreetModel *streetmodel = [[StreetModel alloc] init];

                    streetmodel.street = strstreet;

                    [mstreetArrayModel addObject:streetmodel];

                }

                

                [areaModel setArrayStreet:mstreetArrayModel];

                [mareaArrayModel addObject:areaModel];

            }

            

            [cityModel setArrayArea:mareaArrayModel];

            [mcityArrayModel addObject:cityModel];

        }

        [addrPickerModel setArrayCity:mcityArrayModel];

        [mproviceArrayModel addObject:addrPickerModel];

    }

    self.dataSource = mproviceArrayModel;

    [self getPickerCitiesData];

    [self getPickerAreaData];

    [self getPickerStreetData];

    [self.pickerView reloadAllComponents];

//    if (error) {

//        NSLog(@"%@",error.localizedDescription);

//    }else{

//        NSArray <AddressPickerModel *>*temAddre = [NSArray modelArrayWithClass:[AddressPickerModel class] json:dicParam];

//        self.dataSource = temAddre;

//        [self getPickerCitiesData];

//        [self getPickerAreaData];

//        [self getPickerStreetData];

//        [self.pickerView reloadAllComponents];

//    }

}

 

#pragma mark - pickerView代理

// UIPickerViewDataSource中定义的方法,该方法返回值决定该控件包含多少列

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView

{

    // 返回2表明该控件只包含2列

    return 4;

}

// UIPickerViewDataSource中定义的方法,该方法返回值决定该控件指定列包含多少个列表项

- (NSInteger)pickerView:(UIPickerView *)pickerView

numberOfRowsInComponent:(NSInteger)component

{

    // 如果是第一列,返回authors中元素的个数

    // 即authors包含多少个元素,第一列就包含多少个列表项

    if (component == 0) {

        return self.dataSource.count;

    }else if (component == 1){

        return self.dsCitys.count;

    }else if (component == 2) {

        return self.dsAreas.count;

    }else if (component == 3){

        return self.dsStreets.count;

    }

    return 0;

}

 

 

// UIPickerViewDelegate中定义的方法,该方法返回的NSString将作为

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{

        

        UILabel *lbl = (UILabel *)view;

        

        if (lbl == nil) {

            

            lbl = [[UILabel alloc]init];

            

            //在这里设置字体相关属性

            

            lbl.font = [UIFont systemFontOfSize:12];

            

            lbl.textColor = [UIColor blackColor];

            

            [lbl setTextAlignment:NSTextAlignmentCenter];

            

            [lbl setBackgroundColor:[UIColor clearColor]];

            

        }

        

        //重新加载lbl的文字内容

        

        lbl.text = [self pickerView:pickerView titleForRow:row forComponent:component];

        

        return lbl;

        

 

}

// UIPickerView中指定列、指定列表项上显示的标题

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:

(NSInteger)row forComponent:(NSInteger)component

{

    if (component == 0) {

        

        if (self.dataSource.count >= row) {

            AddressPickerModel* provinceMode = self.dataSource[row];

            return provinceMode.province;

        }

        return @"";

        

    }else if (component == 1){

        if (self.dsCitys.count >= row) {

            CityModel *cityModel = self.dsCitys[row];

            return cityModel.city;

        }

        return @"";

        

        

    }else if (component == 2) {

        if (self.dsAreas.count >= row) {

            AreaModel *areaModel = self.dsAreas[row];

            return areaModel.area;

        }

        return @"";

    }else if (component == 3){

        if (self.dsStreets.count >= row) {

            StreetModel *streetModel = self.dsStreets[row];

            

            return streetModel.street;

        }

        return @"";

    }else{

        return @"";

    }

}

// 当用户选中UIPickerViewDataSource中指定列、指定列表项时激发该方法

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:

(NSInteger)row inComponent:(NSInteger)component

{

    switch (component) {

        case 0:

        {

            self.proviceIndex = row;

            self.cityIndex = 0;

            self.areaIndex = 0;

            self.streetIndex = 0;

            [self getPickerCitiesData];

            [self getPickerAreaData];

            [self getPickerStreetData];

            [self.pickerView reloadComponent:1];

            [self.pickerView reloadComponent:2];

            [self.pickerView reloadComponent:3];

            if (self.dsCitys.count > 0) {

                [pickerView selectRow:0 inComponent:1 animated:YES];

            }

            if (self.dsAreas.count > 0) {

                [pickerView selectRow:0 inComponent:2 animated:YES];

                

            }

            if (self.dsStreets.count > 0) {

                [pickerView selectRow:0 inComponent:3 animated:YES];

            }

            AddressPickerModel *provinceModel = self.dataSource[row];

            self.sprovice = provinceModel.province;

            self.scity = @"";

            self.sarea = @"";

            self.sstreet = @"";

            if (self.dsCitys.count > 0) {

                CityModel *cityModel = self.dsCitys[0];

                self.scity = cityModel.city;

            }

            if (self.dsAreas.count > 0) {

                AreaModel *areaModel = self.dsAreas[0];

                self.sarea = areaModel.area;

            }

            if (self.dsStreets.count > 0) {

                StreetModel *streetModel = self.dsStreets[0];

                self.sstreet = streetModel.street;

            }

            [self setSelectIndex];

            NSMutableString *temMu = [[NSMutableString alloc] init];

            if (![StrUtil isBlankString:self.sprovice]) {

                [temMu appendString:self.sprovice];

            }

            if (![StrUtil isBlankString:self.scity]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.scity]];

            }

            if (![StrUtil isBlankString:self.sarea]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.sarea]];

            }

            if (![StrUtil isBlankString:self.sstreet]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.sstreet]];

            }

            if (![StrUtil isBlankString:temMu]) {

                if (_delegate && [_delegate respondsToSelector:@selector(addressBack:)]) {

                    [_delegate addressBack:temMu];

                }

            }

        }

            break;

        case 1:

        {

//            self.proviceIndex = row;

            self.cityIndex = row;

            self.areaIndex = 0;

            self.streetIndex = 0;

            [self getPickerAreaData];

            [self getPickerStreetData];

            [self.pickerView reloadComponent:2];

            [self.pickerView reloadComponent:3];

            

            if (self.dsAreas.count > 0) {

                [pickerView selectRow:0 inComponent:2 animated:YES];

                

            }

            if (self.dsStreets.count > 0) {

                [pickerView selectRow:0 inComponent:3 animated:YES];

            }

            

            CityModel *cityModel = self.dsCitys[row];

            self.scity = cityModel.city;

            if (self.dsAreas.count > 0) {

                AreaModel *areaModel = self.dsAreas[0];

                self.sarea = areaModel.area;

            }

            if (self.dsStreets.count > 0) {

                StreetModel *streetModel = self.dsStreets[0];

                self.sstreet = streetModel.street;

            }

            [self setSelectIndex];

            NSMutableString *temMu = [[NSMutableString alloc] init];

            if (![StrUtil isBlankString:self.sprovice]) {

                [temMu appendString:self.sprovice];

            }

            if (![StrUtil isBlankString:self.scity]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.scity]];

            }

            if (![StrUtil isBlankString:self.sarea]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.sarea]];

            }

            if (![StrUtil isBlankString:self.sstreet]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.sstreet]];

            }

            if (![StrUtil isBlankString:temMu]) {

                if (_delegate && [_delegate respondsToSelector:@selector(addressBack:)]) {

                    [_delegate addressBack:temMu];

                }

            }

        }

            break;

        case 2:

        {

            self.areaIndex = row;

            self.streetIndex = 0;

            [self getPickerStreetData];

            

            [self.pickerView reloadComponent:3];

            

            if (self.dsStreets.count > 0) {

                [pickerView selectRow:0 inComponent:3 animated:YES];

            }

            

            AreaModel *areaModel = self.dsAreas[row];

            self.sarea = areaModel.area;

            if (self.dsStreets.count > 0) {

                StreetModel *streetModel = self.dsStreets[0];

                self.sstreet = streetModel.street;

            }

            [self setSelectIndex];

            NSMutableString *temMu = [[NSMutableString alloc] init];

            if (![StrUtil isBlankString:self.sprovice]) {

                [temMu appendString:self.sprovice];

            }

            if (![StrUtil isBlankString:self.scity]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.scity]];

            }

            if (![StrUtil isBlankString:self.sarea]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.sarea]];

            }

            if (![StrUtil isBlankString:self.sstreet]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.sstreet]];

            }

            if (![StrUtil isBlankString:temMu]) {

                if (_delegate && [_delegate respondsToSelector:@selector(addressBack:)]) {

                    [_delegate addressBack:temMu];

                }

            }

        }

            break;

        case 3:

        {

            self.streetIndex = row;

            [self.pickerView reloadComponent:3];

            //

            

            //

            //

            StreetModel *streetModel = self.dsStreets[row];

            self.streetIndex = row;

            [self setSelectIndex];

            self.sstreet = streetModel.street;

 

            NSMutableString *temMu = [[NSMutableString alloc] init];

            if (![StrUtil isBlankString:self.sprovice]) {

                [temMu appendString:self.sprovice];

            }

            if (![StrUtil isBlankString:self.scity]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.scity]];

            }

            if (![StrUtil isBlankString:self.sarea]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.sarea]];

            }

            if (![StrUtil isBlankString:self.sstreet]) {

                [temMu appendString:[NSString stringWithFormat:@" %@",self.sstreet]];

            }

            if (![StrUtil isBlankString:temMu]) {

                if (_delegate && [_delegate respondsToSelector:@selector(addressBack:)]) {

                    [_delegate addressBack:temMu];

                }

            }

        }

            break;

            

        default:

            if (_delegate && [_delegate respondsToSelector:@selector(addressBack:)]) {

                [_delegate addressBack:@"北京市"];

            }

            break;

    }

}

- (void)setSelectIndex{

    if (self.dataSource.count >self.proviceIndex) {

        AddressPickerModel *provinceModel = self.dataSource[self.proviceIndex];

        self.sprovice = provinceModel.province;

    }

    if (self.dsCitys.count > self.cityIndex) {

        CityModel *cityModel = self.dsCitys[self.cityIndex];

        self.scity = cityModel.city;

    }

    if (self.dsAreas.count > self.areaIndex) {

        AreaModel *areaModel = self.dsAreas[self.areaIndex];

        self.sarea = areaModel.area;

    }

    if (self.dsStreets.count > self.streetIndex) {

        StreetModel *streetModel = self.dsStreets[self.streetIndex];

        self.sstreet = streetModel.street;

    }

}

// UIPickerViewDelegate中定义的方法,该方法返回的NSString将作为

// UIPickerView中指定列的宽度

- (CGFloat)pickerView:(UIPickerView *)pickerView

    widthForComponent:(NSInteger)component

{

    CGFloat cpickerWidth = self.view.frame.size.width / 4.0;

    return cpickerWidth;

 

}

#pragma mark -重新装在数据

//重新装在城市

- (void)getPickerCitiesData{

    if (self.dataSource.count > self.proviceIndex) {

        self.dsCitys = self.dataSource[self.proviceIndex].arrayCity;

    }else{

        self.dsCitys = nil;

    }

    

}

//重新装在区

- (void)getPickerAreaData{

    if (self.dsCitys.count > self.cityIndex) {

        CityModel *cityModel = self.dsCitys[self.cityIndex];

//        NSLog(@"%@",cityModel);

        self.dsAreas = cityModel.arrayArea;

    }else{

        self.dsAreas = nil;

    }

    

}

//重新装载街道

- (void)getPickerStreetData{

    if (self.dsAreas.count > self.areaIndex) {

        AreaModel *areaModel = self.dsAreas[self.areaIndex];

        self.dsStreets = areaModel.arrayStreet;

    }else{

        self.dsStreets = nil;

    }

}

/*

#pragma mark - Navigation

 

// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/

 

@end

 

 

 
posted @ 2018-08-25 20:08  sundaysios  阅读(628)  评论(0)    收藏  举报