BRPickerView
BRPickerView 封装的是iOS中常用的选择器组件,主要包括:BRDatePickerView
日期选择器(支持年月日、年月等15种日期样式选择,支持设置星期、至今等)、BRTextPickerView
文本选择器(支持单列、多列、省市区、省市、省、自定义多级联动选择)。支持自定义主题样式,适配深色模式,支持将选择器组件添加到指定容器视图。
组件源代码地址:github.com/agiapp/BRPi…
【特别说明】
从2.9.0
版本之后新增了BRTextPickerView
组件,用于替代原先 BRAddressPickerView
和 BRStringPickerView
组件(这两个组件目前做了兼容,可以继续使用,后续会废弃掉,建议使用 BRTextPickerView
组件进行替代)
如果不能找到最新版本,请先执行一下 pod repo update
更新本地仓库,待更新完成后;再执行 pod search BRPickerView
进行搜索,就会看到最新版本。
效果演示
查看并运行 BRPickerViewDemo.xcodeproj
框架Demo运行效果图1 | 框架Demo运行效果图2 |
---|
 |  |
安装
CocoaPods
- 在 Podfile 中添加
pod 'BRPickerView'
。
- 执行
pod install
或 pod update
。
- 导入头文件
#import <BRPickerView.h>
。
安装说明:
pod 'BRPickerView'
:默认是安装全部组件(包含:BRDatePickerView 、 BRTextPickerView ,和废弃的 BRAddressPickerView 、BRStringPickerView 组件)
pod 'BRPickerView/Default'
:仅安装 BRDatePickerView 和 BRTextPickerView 组件
手动导入
- 将与
README.md
同级目录下的 BRPickerView
文件夹拽入项目中
- 导入头文件
#import "BRPickerView.h"
系统要求
使用
时间选择器:BRDatePickerView
查看 BRDatePickerView.h 头文件,里面提供了两种使用方式,参见源码。
typedef NS_ENUM(NSInteger, BRDatePickerMode) {
BRDatePickerModeDate,
BRDatePickerModeDateAndTime,
BRDatePickerModeTime,
BRDatePickerModeCountDownTimer,
BRDatePickerModeYMDHMS,
BRDatePickerModeYMDHM,
BRDatePickerModeYMDH,
BRDatePickerModeMDHM,
BRDatePickerModeYMD,
BRDatePickerModeYM,
BRDatePickerModeY,
BRDatePickerModeMD,
BRDatePickerModeHMS,
BRDatePickerModeHM,
BRDatePickerModeMS,
BRDatePickerModeYQ,
BRDatePickerModeYMW,
BRDatePickerModeYW
};
BRDatePickerView *datePickerView = [[BRDatePickerView alloc]init];
datePickerView.pickerMode = BRDatePickerModeYMD;
datePickerView.title = @"选择年月日";
datePickerView.selectDate = [NSDate br_setYear:2019 month:10 day:30];
datePickerView.minDate = [NSDate br_setYear:1949 month:3 day:12];
datePickerView.maxDate = [NSDate date];
datePickerView.isAutoSelect = YES;
datePickerView.resultBlock = ^(NSDate *selectDate, NSString *selectValue) {
NSLog(@"选择的值:%@", selectValue);
};
BRPickerStyle *customStyle = [[BRPickerStyle alloc]init];
customStyle.pickerColor = BR_RGB_HEX(0xd9dbdf, 1.0f);
customStyle.pickerTextColor = [UIColor redColor];
customStyle.separatorColor = [UIColor redColor];
datePickerView.pickerStyle = customStyle;
[datePickerView show];
时间选择器显示类型的效果图(默认样式):
- 以下4种样式是使用 UIDatePicker 类 进行封装的,支持循环滚动
样式1:BRDatePickerModeDate | 样式2:BRDatePickerModeDateAndTime |
---|
 |  |
样式3:BRDatePickerModeTime | 样式4:BRDatePickerModeCountDownTimer |
---|
 |  |
- 以下11种样式是使用 UIPickerView 类进行封装的。
样式5:BRDatePickerModeYMDHMS | 样式6:BRDatePickerModeYMDHM |
---|
 |  |
样式7:BRDatePickerModeYMDH | 样式8:BRDatePickerModeMDHM |
---|
 |  |
样式9:BRDatePickerModeYMD | 样式10:BRDatePickerModeYM |
---|
 |  |
样式11:BRDatePickerModeY | 样式12:BRDatePickerModeMD |
---|
 |  |
样式13:BRDatePickerModeHMS | 样式14:BRDatePickerModeHM |
---|
 |  |
样式15:BRDatePickerModeMS | |
---|
 | |
设置显示星期:datePickerView.showWeek = YES; | |
---|
 |  |
设置添加至今:datePickerView.addToNow = YES; | 设置显示今天:datePickerView.showToday = YES; |
---|
 |  |
日期单位显示样式:datePickerView.showUnitType = BRShowUnitTypeOnlyCenter; | 设置选择器中间选中行的背景颜色:selectRowColor |
---|
 |  |
BRPickerStyle *customStyle = [[BRPickerStyle alloc]init];
customStyle.selectRowColor = [UIColor blueColor];
customStyle.selectRowTextFont = [UIFont boldSystemFontOfSize:20.0f];
customStyle.selectRowTextColor = [UIColor redColor];
datePickerView.pickerStyle = customStyle;
BRDatePickerModeYMD (默认非中文环境显示英式日期) | BRDatePickerModeYM (默认非中文环境显示英式日期) |
---|
 |  |
datePickerView.pickerStyle = [BRPickerStyle pickerStyleWithThemeColor:[UIColor blueColor]];
datePickerView.pickerStyle = [BRPickerStyle pickerStyleWithDoneTextColor:[UIColor blueColor]];
datePickerView.pickerStyle = [BRPickerStyle pickerStyleWithDoneBtnImage:[UIImage imageNamed:@"icon_close"]];
UIView *headerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 36)];
headerView.backgroundColor = [[UIColor grayColor] colorWithAlphaComponent:0.1f];
NSArray *unitArr = @[@"年", @"月", @"日"];
for (NSInteger i = 0; i < unitArr.count; i++) {
CGFloat width = SCREEN_WIDTH / unitArr.count;
CGFloat orginX = i * (SCREEN_WIDTH / unitArr.count);
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(orginX, 0, width, 36)];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont systemFontOfSize:16.0f];
label.textColor = [UIColor darkGrayColor];
label.text = unitArr[i];
[headerView addSubview:label];
}
datePickerView.pickerHeaderView = headerView;
1.弹框样式模板1 | 2.弹框样式模板2 |
---|
 |  |
3.弹框样式模板3 | 4.添加选择器的头视图:pickerHeaderView |
---|
 |  |
文本选择器:BRTextPickerView
查看 BRTextPickerView.h 头文件,提供了三种类型:
typedef NS_ENUM(NSInteger, BRTextPickerMode) {
BRTextPickerComponentSingle,
BRTextPickerComponentMulti,
BRTextPickerComponentCascade
};
1. 单列文本选择器
BRTextPickerView *textPickerView = [[BRTextPickerView alloc]initWithPickerMode:BRTextPickerComponentSingle];
textPickerView.title = @"学历";
textPickerView.dataSourceArr = @[@"大专以下", @"大专", @"本科", @"硕士", @"博士", @"博士后"];
textPickerView.selectIndex = self.mySelectIndex;
textPickerView.singleResultBlock = ^(BRTextModel * _Nullable model, NSInteger index) {
NSLog(@"选择的值:%@", model.text);
self.mySelectIndex = index;
textField.text = model.text;
};
[textPickerView show];
textPickerView.dataSourceArr = @[@"大专以下", @"大专", @"本科", @"硕士", @"博士", @"博士后"];
textPickerView.fileName = @"education_data.plist";
NSArray *dataArr = @[@{@"code": @"1", @"text": @"大专以下"},
@{@"code": @"2", @"text": @"大专"},
@{@"code": @"3", @"text": @"本科"},
@{@"code": @"4", @"text": @"硕士"},
@{@"code": @"5", @"text": @"博士"},
@{@"code": @"6", @"text": @"博士后"}];
NSArray<BRTextModel *> *modelArr = [NSArray br_modelArrayWithJson:dataArr mapper:nil];
textPickerView.dataSourceArr = modelArr;
说明:当字典key 与 BRTextModel模型的属性不匹配时,需要指定模型属性与字典key的映射关系
BRTextPickerView *textPickerView = [[BRTextPickerView alloc]initWithPickerMode:BRTextPickerComponentSingle];
textPickerView.title = @"融资情况";
NSArray *dataArr = @[@{@"key": @"1001", @"value": @"无融资", @"remark": @""},
@{@"key": @"2001", @"value": @"天使轮", @"remark": @""},
@{@"key": @"3001", @"value": @"A轮", @"remark": @""},
@{@"key": @"4001", @"value": @"B轮", @"remark": @""},
@{@"key": @"5001", @"value": @"C轮以后", @"remark": @""},
@{@"key": @"6001", @"value": @"已上市", @"remark": @""}];
NSDictionary *mapper = @{ @"code": @"key", @"text": @"value", @"extras": @"remark" };
NSArray<BRTextModel *> *modelArr = [NSArray br_modelArrayWithJson:dataArr mapper:mapper];
textPickerView.dataSourceArr = modelArr;
textPickerView.singleResultBlock = ^(BRTextModel * _Nullable model, NSInteger index) {
NSLog(@"选择的值:%@", model.text);
};
[textPickerView show];
学历 | 融资情况 |
---|
 |  |
2. 多列文本选择器
BRTextPickerView *textPickerView = [[BRTextPickerView alloc]initWithPickerMode:BRTextPickerComponentMulti];
textPickerView.title = @"多列文本选择器1";
textPickerView.dataSourceArr = @[@[@"语文", @"数学", @"英语"], @[@"优秀", @"良好"]];
textPickerView.selectIndexs = self.mySelectIndexs;
textPickerView.multiResultBlock = ^(NSArray<BRTextModel *> * _Nullable models, NSArray<NSNumber *> * _Nullable indexs) {
self.mySelectIndexs = indexs;
NSString *selectText = [models br_joinText:@"-"];
NSLog(@"选择的结果:%@", selectText);
};
[textPickerView show];
- 多列文本选择器设置数据源同单列一样,也有3种方式:
textPickerView.dataSourceArr = @[@[@"语文", @"数学", @"英语"], @[@"优秀", @"良好"]];
textPickerView.fileName = @"grade_level_data.plist";
NSArray *subjectDataArr = @[@{@"subject_id": @"11", @"subject": @"语文"}, @{@"subject_id": @"12", @"subject": @"数学"}, @{@"subject_id": @"13", @"subject": @"英语"}];
NSArray *gradeDataArr = @[@{@"grade_id": @"1", @"grade": @"优秀"}, @{@"grade_id": @"2", @"grade": @"良好"}];
NSArray *subjectModelArr = [NSArray br_modelArrayWithJson:subjectDataArr mapper:@{ @"code": @"subject_id", @"text": @"subject" }];
NSArray *gradeModelArr = [NSArray br_modelArrayWithJson:gradeDataArr mapper:@{ @"code": @"grade_id", @"text": @"grade" }];
textPickerView.dataSourceArr = @[subjectModelArr, gradeModelArr];
BRTextPickerView *textPickerView = [[BRTextPickerView alloc]initWithPickerMode:BRTextPickerComponentMulti];
textPickerView.title = @"自定义多列字符串2";
textPickerView.dataSourceArr = @[@[@"01", @"02", @"03", @"04", @"05", @"06", @"07", @"08", @"09", @"10", @"11", @"12"], @[@"00", @"10", @"20", @"30", @"40", @"50"]];
textPickerView.selectIndexs = self.mySelectIndexs;
textPickerView.multiResultBlock = ^(NSArray<BRTextModel *> * _Nullable models, NSArray<NSNumber *> * _Nullable indexs) {
self.mySelectIndexs = indexs;
NSString *selectText = [models br_joinText:@":"];
NSLog(@"选择的结果:%@", selectText);
};
BRPickerStyle *customStyle = [[BRPickerStyle alloc]init];
customStyle.columnWidth = 30;
customStyle.columnSpacing = 60;
customStyle.clearPickerNewStyle = NO;
customStyle.selectRowTextFont = [UIFont boldSystemFontOfSize:20.0f];
customStyle.selectRowTextColor = [UIColor blueColor];
textPickerView.pickerStyle = customStyle;
[textPickerView show];
自定义多列字符串1 | 自定义多列字符串2 |
---|
 |  |
3. 多列联动文本选择器
BRTextPickerView *textPickerView = [[BRTextPickerView alloc]initWithPickerMode:BRTextPickerComponentCascade];
textPickerView.title = @"多列联动文本选择器";
NSArray *dataArr = @[
@{
@"text" : @"浙江省",
@"children" : @[
@{ @"text": @"杭州市", @"children": @[@{ @"text": @"西湖区" }, @{ @"text": @"滨江区" }] },
@{ @"text": @"宁波市", @"children": @[@{ @"text": @"海曙区" }, @{ @"text": @"江北区" }] },
@{ @"text": @"温州市", @"children": @[@{ @"text": @"鹿城区" }, @{ @"text": @"龙湾区" }] }
]
},
@{
@"text" : @"江苏省",
@"children" : @[
@{ @"text": @"南京市", @"children": @[@{ @"text": @"玄武区" }, @{ @"text": @"秦淮区" }] },
@{ @"text": @"苏州市", @"children": @[@{ @"text": @"虎丘区" }, @{ @"text": @"吴中区" }] }
]
},
@{
@"text" : @"辽宁省",
@"children" : @[
@{ @"text": @"沈阳市", @"children": @[@{ @"text": @"沈河区" }, @{ @"text": @"和平区" }] },
@{ @"text": @"大连市", @"children": @[@{ @"text": @"中山区" }, @{ @"text": @"金州区" }] }
]
}
];
textPickerView.dataSourceArr = [NSArray br_modelArrayWithJson:dataArr mapper:nil];
textPickerView.selectIndexs = self.mySelectIndexs;
textPickerView.multiResultBlock = ^(NSArray<BRTextModel *> * _Nullable models, NSArray<NSNumber *> * _Nullable indexs) {
self.mySelectIndexs = indexs;
NSString *selectText = [models br_joinText:@"-"];
NSLog(@"选择的结果:%@", selectText);
};
[textPickerView show];
- 实现省、市、区/县选择(使用本地数据源:region_tree_data.json)
BRTextPickerView *textPickerView = [[BRTextPickerView alloc]initWithPickerMode:BRTextPickerComponentCascade];
textPickerView.title = @"请选择地区";
textPickerView.fileName = @"region_tree_data.json";
textPickerView.showColumnNum = 3;
textPickerView.selectIndexs = self.addressSelectIndexs;
textPickerView.multiResultBlock = ^(NSArray<BRTextModel *> * _Nullable models, NSArray<NSNumber *> * _Nullable indexs) {
self.addressSelectIndexs = indexs;
NSString *selectText = [models br_joinText:@"-"];
NSLog(@"选择的结果:%@", selectText);
textField.text = selectText;
};
[textPickerView show];
样式1:textPickerView.showColumnNum = 3; | 样式2:textPickerView.showColumnNum = 2; |
---|
 |  |
样式3:textPickerView.showColumnNum = 1; | |
 | |
地址文本选择器数据来源于:高德地图行政区划数据源(省、市、区/县),数据更新于2024年7月
高德地图原数据:amap_region_data.json
处理后的树状结构数据1:region_tree_data.json (组件使用本地数据源时,需要下载该文件,放到自己项目中去)
处理后的树状结构数据2:region_list_data.json
{
"status": "1",
"info": "OK",
"districts": [
{
"adcode": "330000",
"name": "浙江省",
"districts" : [
{ "adcode" : "330100", "name": "杭州市", "districts": [{ "adcode" : "330106", "name": "西湖区" }, { "adcode" : "330108", "name": "滨江区" }] },
{ "adcode" : "330200", "name": "宁波市", "districts": [{ "adcode" : "330203", "name": "海曙区" }, { "adcode" : "330205", "name": "江北区" }] },
{ "adcode" : "330300", "name": "温州市", "districts": [{ "adcode" : "330302", "name": "鹿城区" }, { "adcode" : "330303", "name": "龙湾区" }] }
]
},
{
"adcode": "320000",
"name": "江苏省",
"districts" : [
{ "adcode" : "320100", "name": "南京市", "districts": [{ "adcode" : "320102", "name": "玄武区" }, { "adcode" : "320104", "name": "秦淮区" }] },
{ "adcode" : "320500", "name": "苏州市", "districts": [{ "adcode" : "320505", "name": "虎丘区" }, { "adcode" : "320506", "name": "吴中区" }] }
]
},
{
"adcode": "210000",
"name": "辽宁省",
"districts" : [
{ "adcode" : "210100", "name": "沈阳市", "districts": [{ "adcode" : "210103", "name": "沈河区" }, { "adcode" : "210102", "name": "和平区" }] },
{ "adcode" : "210200", "name": "大连市", "districts": [{ "adcode" : "210202", "name": "中山区" }, { "adcode" : "210213", "name": "金州区" }] }
]
}
]
}
BRTextPickerView *textPickerView = [[BRTextPickerView alloc]initWithPickerMode:BRTextPickerComponentCascade];
textPickerView.title = @"多列联动文本选择器";
NSArray *dataArr = ...... responseObject[@"districts"];
NSDictionary *mapper = @{ @"code": @"adcode", @"text": @"name", @"children": @"districts" };
NSArray<BRTextModel *> *modelArr = [NSArray br_modelArrayWithJson:dataArr mapper:mapper];
textPickerView.dataSourceArr = modelArr;
textPickerView.multiResultBlock = ^(NSArray<BRTextModel *> * _Nullable models, NSArray<NSNumber *> * _Nullable indexs) {
NSString *selectText = [models br_joinText:@"-"];
NSLog(@"选择的结果:%@", selectText);
};
[textPickerView show];
{
"Code" : 200,
"Msg" : "获取成功",
"Result" : [
{
"ParentID" : "-1",
"ParentName" : "",
"CategoryID" : "330000",
"CategoryName" : "浙江省"
},
{
"ParentID" : "-1",
"ParentName" : "",
"CategoryID" : "320000",
"CategoryName" : "江苏省"
},
{
"ParentID" : "-1",
"ParentName" : "",
"CategoryID" : "210000",
"CategoryName" : "辽宁省"
},
{
"ParentID" : "330000",
"ParentName" : "浙江省",
"CategoryID" : "330100",
"CategoryName" : "杭州市"
},
{
"ParentID" : "330000",
"ParentName" : "浙江省",
"CategoryID" : "330200",
"CategoryName" : "宁波市"
},
{
"ParentID" : "330000",
"ParentName" : "浙江省",
"CategoryID" : "330300",
"CategoryName" : "温州市"
},
{
"ParentID" : "320000",
"ParentName" : "江苏省",
"CategoryID" : "320100",
"CategoryName" : "南京市"
},
{
"ParentID" : "320000",
"ParentName" : "江苏省",
"CategoryID" : "320500",
"CategoryName" : "苏州市"
},
{
"ParentID" : "210000",
"ParentName" : "辽宁省",
"CategoryID" : "210100",
"CategoryName" : "沈阳市"
},
{
"ParentID" : "210000",
"ParentName" : "辽宁省",
"CategoryID" : "210200",
"CategoryName" : "大连市"
}
]
}
BRTextPickerView *textPickerView = [[BRTextPickerView alloc]initWithPickerMode:BRTextPickerComponentCascade];
textPickerView.title = @"多列联动文本选择器";
NSArray *dataArr = ...... responseObject[@"Result"];
NSDictionary *mapper = @{ @"parentCode": @"ParentID", @"code": @"CategoryID", @"text": @"CategoryName" };
NSArray<BRTextModel *> *listModelArr = [NSArray br_modelArrayWithJson:dataArr mapper:mapper];
NSArray<BRTextModel *> *treeModelArr = [listModelArr br_buildTreeArray];
textPickerView.dataSourceArr = treeModelArr;
textPickerView.multiResultBlock = ^(NSArray<BRTextModel *> * _Nullable models, NSArray<NSNumber *> * _Nullable indexs) {
NSString *selectText = [models br_joinText:@"-"];
NSLog(@"选择的结果:%@", selectText);
NSArray *selectIDs = [models br_getValueArr:@"code"];
};
BRPickerStyle *customStyle = [[BRPickerStyle alloc]init];
customStyle.selectRowTextFont = [UIFont boldSystemFontOfSize:20.0f];
customStyle.selectRowTextColor = [UIColor blueColor];
customStyle.columnWidth = 80;
customStyle.columnSpacing = 10;
textPickerView.pickerStyle = customStyle;
[textPickerView show];
多列联动文本选择器:树状结构数据 | 多列联动文本选择器::扁平结构数据 |
---|
 |  |
补充说明
- 对于一些需要特殊定制弹框的应用场景,可以使用下面的方法把日期选择器/文本选择器到指定容器视图上,实现个性化的弹框需求。
- (void)addPickerToView:(nullable UIView *)view NS_REQUIRES_SUPER;