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

浙公网安备 33010602011771号