This commit is contained in:
DDIsFriend
2023-09-04 16:39:06 +08:00
parent 115f27422e
commit 3b9b465d22
100 changed files with 29843 additions and 7812 deletions

View File

@@ -0,0 +1,51 @@
//
// BRAddressModel.h
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// 省
@interface BRProvinceModel : NSObject
/** 省对应的code或id */
@property (nullable, nonatomic, copy) NSString *code;
/** 省的名称 */
@property (nullable, nonatomic, copy) NSString *name;
/** 城市数组 */
@property (nullable, nonatomic, copy) NSArray *citylist;
/** 记录省选择的索引位置 */
@property (nonatomic, assign) NSInteger index;
@end
/// 市
@interface BRCityModel : NSObject
/** 市对应的code或id */
@property (nullable, nonatomic, copy) NSString *code;
/** 市的名称 */
@property (nullable, nonatomic, copy) NSString *name;
/** 地区数组 */
@property (nullable, nonatomic, copy) NSArray *arealist;
/** 记录市选择的索引位置 */
@property (nonatomic, assign) NSInteger index;
@end
/// 区
@interface BRAreaModel : NSObject
/** 区对应的code或id */
@property (nullable, nonatomic, copy) NSString *code;
/** 区的名称 */
@property (nullable, nonatomic, copy) NSString *name;
/** 记录区选择的索引位置 */
@property (nonatomic, assign) NSInteger index;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,24 @@
//
// BRAddressModel.m
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "BRAddressModel.h"
@implementation BRProvinceModel
@end
@implementation BRCityModel
@end
@implementation BRAreaModel
@end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,127 @@
//
// BRAddressPickerView.h
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import "BRBaseView.h"
#import "BRAddressModel.h"
NS_ASSUME_NONNULL_BEGIN
/// 地址选择器类型
typedef NS_ENUM(NSInteger, BRAddressPickerMode) {
/** 显示【省市区】(默认) */
BRAddressPickerModeArea,
/** 显示【省市】 */
BRAddressPickerModeCity,
/** 显示【省】 */
BRAddressPickerModeProvince
};
typedef void(^BRAddressResultBlock)(BRProvinceModel * _Nullable province, BRCityModel * _Nullable city, BRAreaModel * _Nullable area);
@interface BRAddressPickerView : BRBaseView
/**
//////////////////////////////////////////////////////////////////////////
///
/// 【用法一】
/// 特点:灵活,扩展性强(推荐使用!)
///
////////////////////////////////////////////////////////////////////////*/
/** 地址选择器显示类型 */
@property (nonatomic, assign) BRAddressPickerMode pickerMode;
/** 默认选中的位置(1.传索引数组,如:@[@10, @0, @4]) */
@property (nullable, nonatomic, copy) NSArray <NSNumber *> *selectIndexs;
/** 默认选中的位置(2.传值数组,如:@[@"浙江省", @"杭州市", @"西湖区"]) */
@property (nullable, nonatomic, copy) NSArray <NSString *> *selectValues;
/** 选择结果的回调 */
@property (nullable, nonatomic, copy) BRAddressResultBlock resultBlock;
/** 滚动选择时触发的回调 */
@property (nullable, nonatomic, copy) BRAddressResultBlock changeBlock;
/**
* 地区数据源不传或为nil默认就获取本地 BRCity.json 文件的数据)
* 1.可以传 JSON数组要注意 层级结构 和 key 要与 BRCity.json 保持一致
* 2.可以传 模型数组(NSArray <BRProvinceModel *> * 类型),自己解析数据源 只需要注意层级结构就行
*/
@property (nullable, nonatomic, copy) NSArray *dataSourceArr;
/// 初始化地址选择器
/// @param pickerMode 地址选择器显示类型
- (instancetype)initWithPickerMode:(BRAddressPickerMode)pickerMode;
/// 弹出选择器视图
- (void)show;
/// 关闭选择器视图
- (void)dismiss;
//================================================= 华丽的分割线 =================================================
/**
//////////////////////////////////////////////////////////////////////////
///
/// 【用法二】:快捷使用,直接选择下面其中的一个方法进行使用
/// 特点:快捷,方便
///
////////////////////////////////////////////////////////////////////////*/
/**
* 1.显示地址选择器
*
* @param selectIndexs 默认选中的值(传索引数组,如:@[@10, @0, @4])
* @param resultBlock 选择后的回调
*
*/
+ (void)showAddressPickerWithSelectIndexs:(nullable NSArray <NSNumber *> *)selectIndexs
resultBlock:(nullable BRAddressResultBlock)resultBlock;
/**
* 2.显示地址选择器
*
* @param mode 地址选择器显示类型
* @param selectIndexs 默认选中的值(传索引数组,如:@[@10, @0, @4])
* @param isAutoSelect 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO
* @param resultBlock 选择后的回调
*
*/
+ (void)showAddressPickerWithMode:(BRAddressPickerMode)mode
selectIndexs:(nullable NSArray <NSNumber *> *)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRAddressResultBlock)resultBlock;
/**
* 3.显示地址选择器
*
* @param mode 地址选择器显示类型
* @param dataSource 地区数据源
* @param selectIndexs 默认选中的值(传索引数组,如:@[@10, @0, @4])
* @param isAutoSelect 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO
* @param resultBlock 选择后的回调
*
*/
+ (void)showAddressPickerWithMode:(BRAddressPickerMode)mode
dataSource:(nullable NSArray *)dataSource
selectIndexs:(nullable NSArray <NSNumber *> *)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRAddressResultBlock)resultBlock;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,562 @@
//
// BRAddressPickerView.m
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "BRAddressPickerView.h"
#import "NSBundle+BRPickerView.h"
@interface BRAddressPickerView ()<UIPickerViewDataSource, UIPickerViewDelegate>
//
@property (nonatomic, strong) UIPickerView *pickerView;
//
@property(nonatomic, copy) NSArray *provinceModelArr;
//
@property(nonatomic, copy) NSArray *cityModelArr;
//
@property(nonatomic, copy) NSArray *areaModelArr;
//
@property(nonatomic, strong) BRProvinceModel *selectProvinceModel;
//
@property(nonatomic, strong) BRCityModel *selectCityModel;
//
@property(nonatomic, strong) BRAreaModel *selectAreaModel;
//
@property(nonatomic, assign) NSInteger provinceIndex;
//
@property(nonatomic, assign) NSInteger cityIndex;
//
@property(nonatomic, assign) NSInteger areaIndex;
@property (nonatomic, copy) NSArray <NSString *>* mSelectValues;
@end
@implementation BRAddressPickerView
#pragma mark - 1.
+ (void)showAddressPickerWithSelectIndexs:(NSArray <NSNumber *>*)selectIndexs
resultBlock:(BRAddressResultBlock)resultBlock {
[self showAddressPickerWithMode:BRAddressPickerModeArea dataSource:nil selectIndexs:selectIndexs isAutoSelect:NO resultBlock:resultBlock];
}
#pragma mark - 2.
+ (void)showAddressPickerWithMode:(BRAddressPickerMode)mode
selectIndexs:(NSArray <NSNumber *>*)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(BRAddressResultBlock)resultBlock {
[self showAddressPickerWithMode:mode dataSource:nil selectIndexs:selectIndexs isAutoSelect:isAutoSelect resultBlock:resultBlock];
}
#pragma mark - 3.
+ (void)showAddressPickerWithMode:(BRAddressPickerMode)mode
dataSource:(NSArray *)dataSource
selectIndexs:(NSArray <NSNumber *>*)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(BRAddressResultBlock)resultBlock {
//
BRAddressPickerView *addressPickerView = [[BRAddressPickerView alloc] initWithPickerMode:mode];
addressPickerView.dataSourceArr = dataSource;
addressPickerView.selectIndexs = selectIndexs;
addressPickerView.isAutoSelect = isAutoSelect;
addressPickerView.resultBlock = resultBlock;
//
[addressPickerView show];
}
#pragma mark -
- (instancetype)initWithPickerMode:(BRAddressPickerMode)pickerMode {
if (self = [super init]) {
self.pickerMode = pickerMode;
}
return self;
}
#pragma mark -
- (void)handlerPickerData {
if (self.dataSourceArr && self.dataSourceArr.count > 0) {
id item = [self.dataSourceArr firstObject];
//
if ([item isKindOfClass:[BRProvinceModel class]]) {
self.provinceModelArr = self.dataSourceArr;
} else {
self.provinceModelArr = [self getProvinceModelArr:self.dataSourceArr];
}
} else {
// 使
NSArray *dataSource = [self br_addressJsonArray];
if (!dataSource || dataSource.count == 0) {
return;
}
self.dataSourceArr = dataSource;
self.provinceModelArr = [self getProvinceModelArr:self.dataSourceArr];
}
//
[self handlerDefaultSelectValue];
}
#pragma mark - JSON
- (NSArray *)br_addressJsonArray {
static NSArray *cityArray = nil;
if (!cityArray) {
// BRAddressPickerView.bundle
NSBundle *containnerBundle = [NSBundle bundleForClass:[BRAddressPickerView class]];
NSString *bundlePath = [containnerBundle pathForResource:@"BRAddressPickerView" ofType:@"bundle"];
NSBundle *addressPickerBundle = [NSBundle bundleWithPath:bundlePath];
// bundleJSON
NSString *filePath = [addressPickerBundle pathForResource:@"BRCity" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
cityArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
}
return cityArray;
}
#pragma mark -
- (NSArray <BRProvinceModel *>*)getProvinceModelArr:(NSArray *)dataSourceArr {
NSMutableArray *tempArr1 = [NSMutableArray array];
for (NSDictionary *proviceDic in dataSourceArr) {
BRProvinceModel *proviceModel = [[BRProvinceModel alloc]init];
proviceModel.code = [proviceDic objectForKey:@"code"];
proviceModel.name = [proviceDic objectForKey:@"name"];
proviceModel.index = [dataSourceArr indexOfObject:proviceDic];
NSArray *cityList = [proviceDic.allKeys containsObject:@"cityList"] ? [proviceDic objectForKey:@"cityList"] : [proviceDic objectForKey:@"citylist"];
NSMutableArray *tempArr2 = [NSMutableArray array];
for (NSDictionary *cityDic in cityList) {
BRCityModel *cityModel = [[BRCityModel alloc]init];
cityModel.code = [cityDic objectForKey:@"code"];
cityModel.name = [cityDic objectForKey:@"name"];
cityModel.index = [cityList indexOfObject:cityDic];
NSArray *areaList = [cityDic.allKeys containsObject:@"areaList"] ? [cityDic objectForKey:@"areaList"] : [cityDic objectForKey:@"arealist"];
NSMutableArray *tempArr3 = [NSMutableArray array];
for (NSDictionary *areaDic in areaList) {
BRAreaModel *areaModel = [[BRAreaModel alloc]init];
areaModel.code = [areaDic objectForKey:@"code"];
areaModel.name = [areaDic objectForKey:@"name"];
areaModel.index = [areaList indexOfObject:areaDic];
[tempArr3 addObject:areaModel];
}
cityModel.arealist = [tempArr3 copy];
[tempArr2 addObject:cityModel];
}
proviceModel.citylist = [tempArr2 copy];
[tempArr1 addObject:proviceModel];
}
return [tempArr1 copy];
}
#pragma mark -
- (void)handlerDefaultSelectValue {
__block NSString *selectProvinceName = nil;
__block NSString *selectCityName = nil;
__block NSString *selectAreaName = nil;
if (self.mSelectValues.count > 0) {
selectProvinceName = self.mSelectValues.count > 0 ? self.mSelectValues[0] : nil;
selectCityName = self.mSelectValues.count > 1 ? self.mSelectValues[1] : nil;
selectAreaName = self.mSelectValues.count > 2 ? self.mSelectValues[2] : nil;
}
__weak typeof(self) weakSelf = self;
if (self.pickerMode == BRAddressPickerModeProvince || self.pickerMode == BRAddressPickerModeCity || self.pickerMode == BRAddressPickerModeArea) {
if (self.selectIndexs.count > 0) {
NSInteger provinceIndex = [self.selectIndexs[0] integerValue];
self.provinceIndex = (provinceIndex > 0 && provinceIndex < self.provinceModelArr.count) ? provinceIndex : 0;
self.selectProvinceModel = self.provinceModelArr.count > self.provinceIndex ? self.provinceModelArr[self.provinceIndex] : nil;
} else {
self.provinceIndex = 0;
self.selectProvinceModel = self.provinceModelArr.count > 0 ? self.provinceModelArr[0] : nil;
[self.provinceModelArr enumerateObjectsUsingBlock:^(BRProvinceModel * _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
if (selectProvinceName && [model.name isEqualToString:selectProvinceName]) {
weakSelf.provinceIndex = idx;
weakSelf.selectProvinceModel = model;
*stop = YES;
}
}];
}
}
if (self.pickerMode == BRAddressPickerModeCity || self.pickerMode == BRAddressPickerModeArea) {
self.cityModelArr = [self getCityModelArray:self.provinceIndex];
if (self.selectIndexs.count > 0) {
NSInteger cityIndex = self.selectIndexs.count > 1 ? [self.selectIndexs[1] integerValue] : 0;
self.cityIndex = (cityIndex > 0 && cityIndex < self.cityModelArr.count) ? cityIndex : 0;
self.selectCityModel = self.cityModelArr.count > self.cityIndex ? self.cityModelArr[self.cityIndex] : nil;
} else {
self.cityIndex = 0;
self.selectCityModel = self.cityModelArr.count > 0 ? self.cityModelArr[0] : nil;
[self.cityModelArr enumerateObjectsUsingBlock:^(BRCityModel * _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
if (selectCityName && [model.name isEqualToString:selectCityName]) {
weakSelf.cityIndex = idx;
weakSelf.selectCityModel = model;
*stop = YES;
}
}];
}
}
if (self.pickerMode == BRAddressPickerModeArea) {
self.areaModelArr = [self getAreaModelArray:self.provinceIndex cityIndex:self.cityIndex];
if (self.selectIndexs.count > 0) {
NSInteger areaIndex = self.selectIndexs.count > 2 ? [self.selectIndexs[2] integerValue] : 0;
self.areaIndex = (areaIndex > 0 && areaIndex < self.areaModelArr.count) ? areaIndex : 0;
self.selectAreaModel = self.areaModelArr.count > self.areaIndex ? self.areaModelArr[self.areaIndex] : nil;
} else {
self.areaIndex = 0;
self.selectAreaModel = self.areaModelArr.count > 0 ? self.areaModelArr[0] : nil;
[self.areaModelArr enumerateObjectsUsingBlock:^(BRAreaModel * _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
if (selectAreaName && [model.name isEqualToString:selectAreaName]) {
weakSelf.areaIndex = idx;
weakSelf.selectAreaModel = model;
*stop = YES;
}
}];
}
}
}
//
- (NSArray *)getCityModelArray:(NSInteger)provinceIndex {
BRProvinceModel *provinceModel = self.provinceModelArr[provinceIndex];
//
return provinceModel.citylist;
}
//
- (NSArray *)getAreaModelArray:(NSInteger)provinceIndex cityIndex:(NSInteger)cityIndex {
BRProvinceModel *provinceModel = self.provinceModelArr[provinceIndex];
if (provinceModel.citylist && provinceModel.citylist.count > 0) {
BRCityModel *cityModel = provinceModel.citylist[cityIndex];
//
return cityModel.arealist;
} else {
return nil;
}
}
#pragma mark -
- (UIPickerView *)pickerView {
if (!_pickerView) {
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
_pickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, self.pickerStyle.titleBarHeight + pickerHeaderViewHeight, self.keyView.bounds.size.width, self.pickerStyle.pickerHeight)];
_pickerView.backgroundColor = self.pickerStyle.pickerColor;
_pickerView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
_pickerView.dataSource = self;
_pickerView.delegate = self;
}
return _pickerView;
}
#pragma mark - UIPickerViewDataSource
// 1. pickerView
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
switch (self.pickerMode) {
case BRAddressPickerModeProvince:
return 1;
break;
case BRAddressPickerModeCity:
return 2;
break;
case BRAddressPickerModeArea:
return 3;
break;
default:
break;
}
}
// 2. pickerView
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (component == 0) {
//
return self.provinceModelArr.count;
}
if (component == 1) {
//
return self.cityModelArr.count;
}
if (component == 2) {
//
return self.areaModelArr.count;
}
return 0;
}
#pragma mark - UIPickerViewDelegate
// 3. pickerView
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view {
// 1. row
UILabel *label = (UILabel *)view;
if (!label) {
label = [[UILabel alloc]init];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = self.pickerStyle.pickerTextFont;
label.textColor = self.pickerStyle.pickerTextColor;
//
label.adjustsFontSizeToFitWidth = YES;
//
label.minimumScaleFactor = 0.5f;
}
if (component == 0) {
BRProvinceModel *model = self.provinceModelArr[row];
label.text = model.name;
} else if (component == 1) {
BRCityModel *model = self.cityModelArr[row];
label.text = model.name;
} else if (component == 2) {
BRAreaModel *model = self.areaModelArr[row];
label.text = model.name;
}
// 2.
[self.pickerStyle setupPickerSelectRowStyle:pickerView titleForRow:row forComponent:component];
return label;
}
// 4. pickerView
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component == 0) { //
//
self.provinceIndex = row;
switch (self.pickerMode) {
case BRAddressPickerModeProvince:
{
self.selectProvinceModel = self.provinceModelArr.count > self.provinceIndex ? self.provinceModelArr[self.provinceIndex] : nil;
self.selectCityModel = nil;
self.selectAreaModel = nil;
}
break;
case BRAddressPickerModeCity:
{
self.cityModelArr = [self getCityModelArray:self.provinceIndex];
[self.pickerView reloadComponent:1];
[self.pickerView selectRow:0 inComponent:1 animated:YES];
self.selectProvinceModel = self.provinceModelArr.count > self.provinceIndex ? self.provinceModelArr[self.provinceIndex] : nil;
self.selectCityModel = self.cityModelArr.count > 0 ? self.cityModelArr[0] : nil;
self.selectAreaModel = nil;
}
break;
case BRAddressPickerModeArea:
{
self.cityModelArr = [self getCityModelArray:self.provinceIndex];
self.areaModelArr = [self getAreaModelArray:self.provinceIndex cityIndex:0];
[self.pickerView reloadComponent:1];
[self.pickerView selectRow:0 inComponent:1 animated:YES];
[self.pickerView reloadComponent:2];
[self.pickerView selectRow:0 inComponent:2 animated:YES];
self.selectProvinceModel = self.provinceModelArr.count > self.provinceIndex ? self.provinceModelArr[self.provinceIndex] : nil;
self.selectCityModel = self.cityModelArr.count > 0 ? self.cityModelArr[0] : nil;
self.selectAreaModel = self.areaModelArr.count > 0 ? self.areaModelArr[0] : nil;
}
break;
default:
break;
}
}
if (component == 1) { //
//
self.cityIndex = row;
switch (self.pickerMode) {
case BRAddressPickerModeCity:
{
self.selectCityModel = self.cityModelArr.count > self.cityIndex ? self.cityModelArr[self.cityIndex] : nil;
self.selectAreaModel = nil;
}
break;
case BRAddressPickerModeArea:
{
self.areaModelArr = [self getAreaModelArray:self.provinceIndex cityIndex:self.cityIndex];
[self.pickerView reloadComponent:2];
[self.pickerView selectRow:0 inComponent:2 animated:YES];
self.selectCityModel = self.cityModelArr.count > self.cityIndex ? self.cityModelArr[self.cityIndex] : nil;
self.selectAreaModel = self.areaModelArr.count > 0 ? self.areaModelArr[0] : nil;
}
break;
default:
break;
}
}
if (component == 2) { //
//
self.areaIndex = row;
if (self.pickerMode == BRAddressPickerModeArea) {
self.selectAreaModel = self.areaModelArr.count > self.areaIndex ? self.areaModelArr[self.areaIndex] : nil;
}
}
// changeBlock
if (self.changeBlock) {
self.changeBlock(self.selectProvinceModel, self.selectCityModel, self.selectAreaModel);
}
// resultBlock
if (self.isAutoSelect) {
if (self.resultBlock) {
self.resultBlock(self.selectProvinceModel, self.selectCityModel, self.selectAreaModel);
}
}
}
//
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
return self.pickerStyle.rowHeight;
}
#pragma mark -
- (void)reloadData {
// 1.
[self handlerPickerData];
// 2.
[self.pickerView reloadAllComponents];
// 3.
if (self.pickerMode == BRAddressPickerModeProvince) {
[self.pickerView selectRow:self.provinceIndex inComponent:0 animated:YES];
} else if (self.pickerMode == BRAddressPickerModeCity) {
[self.pickerView selectRow:self.provinceIndex inComponent:0 animated:YES];
[self.pickerView selectRow:self.cityIndex inComponent:1 animated:YES];
} else if (self.pickerMode == BRAddressPickerModeArea) {
[self.pickerView selectRow:self.provinceIndex inComponent:0 animated:YES];
[self.pickerView selectRow:self.cityIndex inComponent:1 animated:YES];
[self.pickerView selectRow:self.areaIndex inComponent:2 animated:YES];
}
}
- (void)addPickerToView:(UIView *)view {
// 1.
if (view) {
// view view 使
[view setNeedsLayout];
[view layoutIfNeeded];
self.frame = view.bounds;
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
CGFloat pickerFooterViewHeight = self.pickerFooterView ? self.pickerFooterView.bounds.size.height : 0;
self.pickerView.frame = CGRectMake(0, pickerHeaderViewHeight, view.bounds.size.width, view.bounds.size.height - pickerHeaderViewHeight - pickerFooterViewHeight);
[self addSubview:self.pickerView];
} else {
// iOS16 pickerView frame
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
self.pickerView.frame = CGRectMake(0, self.pickerStyle.titleBarHeight + pickerHeaderViewHeight, self.keyView.bounds.size.width, self.pickerStyle.pickerHeight);
[self.alertView addSubview:self.pickerView];
}
// 线
if (self.pickerStyle.clearPickerNewStyle) {
[self.pickerStyle addSeparatorLineView:self.pickerView];
}
// 2.
[self reloadData];
__weak typeof(self) weakSelf = self;
self.doneBlock = ^{
// block
if (weakSelf.resultBlock) {
weakSelf.resultBlock(weakSelf.selectProvinceModel, weakSelf.selectCityModel, weakSelf.selectAreaModel);
}
};
[super addPickerToView:view];
}
#pragma mark -
- (void)addSubViewToPicker:(UIView *)customView {
[self.pickerView addSubview:customView];
}
#pragma mark -
- (void)show {
[self addPickerToView:nil];
}
#pragma mark -
- (void)dismiss {
[self removePickerFromView:nil];
}
#pragma mark - setter
- (void)setSelectValues:(NSArray<NSString *> *)selectValues {
self.mSelectValues = selectValues;
}
#pragma mark - getter
- (NSArray *)provinceModelArr {
if (!_provinceModelArr) {
_provinceModelArr = [NSArray array];
}
return _provinceModelArr;
}
- (NSArray *)cityModelArr {
if (!_cityModelArr) {
_cityModelArr = [NSArray array];
}
return _cityModelArr;
}
- (NSArray *)areaModelArr {
if (!_areaModelArr) {
_areaModelArr = [NSArray array];
}
return _areaModelArr;
}
- (BRProvinceModel *)selectProvinceModel {
if (!_selectProvinceModel) {
_selectProvinceModel = [[BRProvinceModel alloc]init];
}
return _selectProvinceModel;
}
- (BRCityModel *)selectCityModel {
if (!_selectCityModel) {
_selectCityModel = [[BRCityModel alloc]init];
_selectCityModel.code = @"";
_selectCityModel.name = @"";
}
return _selectCityModel;
}
- (BRAreaModel *)selectAreaModel {
if (!_selectAreaModel) {
_selectAreaModel = [[BRAreaModel alloc]init];
_selectAreaModel.code = @"";
_selectAreaModel.name = @"";
}
return _selectAreaModel;
}
- (NSArray *)dataSourceArr {
if (!_dataSourceArr) {
_dataSourceArr = [NSArray array];
}
return _dataSourceArr;
}
- (NSArray<NSString *> *)mSelectValues {
if (!_mSelectValues) {
_mSelectValues = [NSArray array];
}
return _mSelectValues;
}
- (NSArray<NSNumber *> *)selectIndexs {
if (!_selectIndexs) {
_selectIndexs = [NSArray array];
}
return _selectIndexs;
}
@end

17
Pods/BRPickerView/BRPickerView/BRPickerView.h generated Executable file
View File

@@ -0,0 +1,17 @@
//
// BRPickerView.h
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#ifndef BRPickerView_h
#define BRPickerView_h
#import "BRDatePickerView.h"
#import "BRAddressPickerView.h"
#import "BRStringPickerView.h"
#endif /* BRPickerView_h */

View File

@@ -0,0 +1,76 @@
//
// BaseView.h
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import <UIKit/UIKit.h>
#import "BRPickerStyle.h"
NS_ASSUME_NONNULL_BEGIN
typedef void(^BRCancelBlock)(void);
typedef void(^BRDoneClickBlock)(void);
@interface BRBaseView : UIView
/** 选择器标题 */
@property (nullable, nonatomic, copy) NSString *title;
/** 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO */
@property (nonatomic, assign) BOOL isAutoSelect;
/** 自定义UI样式不传或为nil时是默认样式 */
@property (nullable, nonatomic, strong) BRPickerStyle *pickerStyle;
/** 取消选择的回调 */
@property (nullable, nonatomic, copy) BRCancelBlock cancelBlock;
/** accessory view for above picker view. default is nil */
@property (nullable, nonatomic, strong) UIView *pickerHeaderView;
/** accessory view below picker view. default is nil */
@property (nullable, nonatomic, strong) UIView *pickerFooterView;
/// 确定按钮点击事件的回调
/// 应用场景:如果是自定义确定按钮,需要在该按钮点击事件方法里,执行一下 doneBlock 回调。目的是触发组件内部执行 resultBlock 回调,回调选择的值
@property (nullable, nonatomic, copy) BRDoneClickBlock doneBlock;
/** 弹框视图(使用场景:可以在 alertView 上添加选择器的自定义背景视图) */
@property (nullable, nonatomic, strong) UIView *alertView;
/** 组件的父视图:可以传 自己获取的 keyWindow或页面的 view */
@property (nullable, nonatomic, strong) UIView *keyView;
/// 刷新选择器数据
/// 应用场景:动态更新数据源、动态更新选择的值、选择器类型切换等
- (void)reloadData;
/// 扩展一:添加选择器到指定容器视图上
/// 应用场景:可将中间的滚轮选择器 pickerView 视图(不包含蒙层及标题栏)添加到任何自定义视图上(会自动填满容器视图),也方便自定义更多的弹框样式
/// 补充说明:如果是自定义确定按钮,需要回调默认选择的值:只需在自定义确定按钮的点击事件方法里执行一下 doneBlock 回调(目的是去触发组件内部执行 resultBlock 回调,进而回调默认选择的值)
/// @param view 容器视图
- (void)addPickerToView:(nullable UIView *)view NS_REQUIRES_SUPER;
/// 从指定容器视图上移除选择器
/// @param view 容器视图
- (void)removePickerFromView:(nullable UIView *)view;
/// 扩展二添加自定义视图到选择器pickerView
/// 应用场景:可以添加一些固定的标题、单位等到选择器中间
/// @param customView 自定义视图
- (void)addSubViewToPicker:(UIView *)customView;
/// 扩展三添加自定义视图到标题栏titleBarView
/// 应用场景:可以添加一些子控件到标题栏
/// @param customView 自定义视图
- (void)addSubViewToTitleBar:(UIView *)customView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,398 @@
//
// BaseView.m
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "BRBaseView.h"
@interface BRBaseView ()
//
@property (nonatomic, strong) UIView *maskView;
//
@property (nonatomic, strong) UIView *titleBarView;
//
@property (nonatomic, strong) UIButton *cancelBtn;
//
@property (nonatomic, strong) UIButton *doneBtn;
//
@property (nonatomic, strong) UILabel *titleLabel;
//
@property (nonatomic, assign) CGFloat cancelBtnMargin;
//
@property (nonatomic, assign) CGFloat doneBtnMargin;
@end
@implementation BRBaseView
- (void)initUI {
self.frame = self.keyView.bounds;
//
self.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
if (!self.pickerStyle.hiddenMaskView) {
[self addSubview:self.maskView];
}
[self addSubview:self.alertView];
//
if (!self.pickerStyle.hiddenTitleBarView) {
[self.alertView addSubview:self.titleBarView];
[self.alertView sendSubviewToBack:self.titleBarView];
if (!self.pickerStyle.hiddenTitleLabel) {
[self.titleBarView addSubview:self.titleLabel];
}
if (!self.pickerStyle.hiddenCancelBtn) {
[self.titleBarView addSubview:self.cancelBtn];
//
if (self.pickerStyle.cancelBtnFrame.origin.x < self.bounds.size.width / 2) {
self.cancelBtnMargin = self.pickerStyle.cancelBtnFrame.origin.x;
} else {
self.cancelBtnMargin = self.bounds.size.width - self.pickerStyle.cancelBtnFrame.origin.x - self.pickerStyle.cancelBtnFrame.size.width;
}
}
if (!self.pickerStyle.hiddenDoneBtn) {
[self.titleBarView addSubview:self.doneBtn];
//
if (self.pickerStyle.doneBtnFrame.origin.x < self.bounds.size.width / 2) {
self.doneBtnMargin = self.pickerStyle.doneBtnFrame.origin.x;
} else {
self.doneBtnMargin = self.bounds.size.width - self.pickerStyle.doneBtnFrame.origin.x - self.pickerStyle.doneBtnFrame.size.width;
}
}
}
}
#pragma mark -
- (void)layoutSubviews {
[super layoutSubviews];
if (_cancelBtn || _doneBtn) {
if (@available(iOS 11.0, *)) {
UIEdgeInsets safeInsets = self.safeAreaInsets;
if (_cancelBtn) {
CGRect cancelBtnFrame = self.pickerStyle.cancelBtnFrame;
if (cancelBtnFrame.origin.x < MIN(self.bounds.size.width / 2, self.bounds.size.height / 2)) {
cancelBtnFrame.origin.x += safeInsets.left;
} else {
cancelBtnFrame.origin.x = self.bounds.size.width - cancelBtnFrame.size.width - safeInsets.right - self.cancelBtnMargin;
}
self.cancelBtn.frame = cancelBtnFrame;
}
if (_doneBtn) {
CGRect doneBtnFrame = self.pickerStyle.doneBtnFrame;
if (doneBtnFrame.origin.x < MIN(self.bounds.size.width / 2, self.bounds.size.height / 2)) {
doneBtnFrame.origin.x += safeInsets.left;
} else {
doneBtnFrame.origin.x = self.bounds.size.width - doneBtnFrame.size.width - safeInsets.right - self.doneBtnMargin;
}
self.doneBtn.frame = doneBtnFrame;
}
}
}
if (_alertView && self.pickerStyle.topCornerRadius > 0) {
//
[BRPickerStyle br_setView:_alertView roundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight withRadius:self.pickerStyle.topCornerRadius];
}
}
#pragma mark -
- (UIView *)maskView {
if (!_maskView) {
_maskView = [[UIView alloc]initWithFrame:self.keyView.bounds];
_maskView.backgroundColor = self.pickerStyle.maskColor;
//
_maskView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_maskView.userInteractionEnabled = YES;
UITapGestureRecognizer *myTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(didTapMaskView:)];
[_maskView addGestureRecognizer:myTap];
}
return _maskView;
}
#pragma mark -
- (UIView *)alertView {
if (!_alertView) {
CGFloat accessoryViewHeight = 0;
if (self.pickerHeaderView) {
accessoryViewHeight += self.pickerHeaderView.bounds.size.height;
}
if (self.pickerFooterView) {
accessoryViewHeight += self.pickerFooterView.bounds.size.height;
}
CGFloat height = self.pickerStyle.titleBarHeight + self.pickerStyle.pickerHeight + self.pickerStyle.paddingBottom + accessoryViewHeight;
_alertView = [[UIView alloc]initWithFrame:CGRectMake(0, self.keyView.bounds.size.height - height, self.keyView.bounds.size.width, height)];
_alertView.backgroundColor = self.pickerStyle.alertViewColor ? self.pickerStyle.alertViewColor : self.pickerStyle.pickerColor;
if (!self.pickerStyle.topCornerRadius && !self.pickerStyle.hiddenShadowLine) {
// 线
UIView *shadowLineView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _alertView.frame.size.width, self.pickerStyle.shadowLineHeight)];
shadowLineView.backgroundColor = self.pickerStyle.shadowLineColor;
shadowLineView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[_alertView addSubview:shadowLineView];
}
_alertView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
}
return _alertView;
}
#pragma mark -
- (UIView *)titleBarView {
if (!_titleBarView) {
_titleBarView =[[UIView alloc]initWithFrame:CGRectMake(0, 0, self.keyView.bounds.size.width, self.pickerStyle.titleBarHeight)];
_titleBarView.backgroundColor = self.pickerStyle.titleBarColor;
_titleBarView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
if (!self.pickerStyle.hiddenTitleLine) {
// 线
UIView *titleLineView = [[UIView alloc]initWithFrame:CGRectMake(0, _titleBarView.frame.size.height - 0.5f, _titleBarView.frame.size.width, 0.5f)];
titleLineView.backgroundColor = self.pickerStyle.titleLineColor;
titleLineView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[_titleBarView addSubview:titleLineView];
}
}
return _titleBarView;
}
#pragma mark -
- (UIButton *)cancelBtn {
if (!_cancelBtn) {
_cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_cancelBtn.frame = self.pickerStyle.cancelBtnFrame;
_cancelBtn.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
_cancelBtn.backgroundColor = self.pickerStyle.cancelColor;;
_cancelBtn.titleLabel.font = self.pickerStyle.cancelTextFont;
[_cancelBtn setTitleColor:self.pickerStyle.cancelTextColor forState:UIControlStateNormal];
if (self.pickerStyle.cancelBtnImage) {
[_cancelBtn setImage:self.pickerStyle.cancelBtnImage forState:UIControlStateNormal];
}
if (self.pickerStyle.cancelBtnTitle) {
[_cancelBtn setTitle:self.pickerStyle.cancelBtnTitle forState:UIControlStateNormal];
}
[_cancelBtn addTarget:self action:@selector(clickCancelBtn) forControlEvents:UIControlEventTouchUpInside];
//
if (self.pickerStyle.cancelBorderStyle == BRBorderStyleSolid) {
_cancelBtn.layer.cornerRadius = self.pickerStyle.cancelCornerRadius > 0 ? self.pickerStyle.cancelCornerRadius : 6.0f;
_cancelBtn.layer.borderColor = self.pickerStyle.cancelTextColor.CGColor;
_cancelBtn.layer.borderWidth = self.pickerStyle.cancelBorderWidth > 0 ? self.pickerStyle.cancelBorderWidth : 1.0f;
_cancelBtn.layer.masksToBounds = YES;
} else if (self.pickerStyle.cancelBorderStyle == BRBorderStyleFill) {
_cancelBtn.layer.cornerRadius = self.pickerStyle.cancelCornerRadius > 0 ? self.pickerStyle.cancelCornerRadius : 6.0f;
_cancelBtn.layer.masksToBounds = YES;
}
}
return _cancelBtn;
}
#pragma mark -
- (UIButton *)doneBtn {
if (!_doneBtn) {
_doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_doneBtn.frame = self.pickerStyle.doneBtnFrame;
_doneBtn.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
_doneBtn.backgroundColor = self.pickerStyle.doneColor;
if (self.pickerStyle.doneBtnImage) {
[_doneBtn setImage:self.pickerStyle.doneBtnImage forState:UIControlStateNormal];
}
if (self.pickerStyle.doneBtnTitle) {
_doneBtn.titleLabel.font = self.pickerStyle.doneTextFont;
[_doneBtn setTitleColor:self.pickerStyle.doneTextColor forState:UIControlStateNormal];
[_doneBtn setTitle:self.pickerStyle.doneBtnTitle forState:UIControlStateNormal];
}
[_doneBtn addTarget:self action:@selector(clickDoneBtn) forControlEvents:UIControlEventTouchUpInside];
//
if (self.pickerStyle.doneBorderStyle == BRBorderStyleSolid) {
_doneBtn.layer.cornerRadius = self.pickerStyle.doneCornerRadius > 0 ? self.pickerStyle.doneCornerRadius : 6.0f;
_doneBtn.layer.borderColor = self.pickerStyle.doneTextColor.CGColor;
_doneBtn.layer.borderWidth = self.pickerStyle.doneBorderWidth > 0 ? self.pickerStyle.doneBorderWidth : 1.0f;
_doneBtn.layer.masksToBounds = YES;
} else if (self.pickerStyle.doneBorderStyle == BRBorderStyleFill) {
_doneBtn.layer.cornerRadius = self.pickerStyle.doneCornerRadius > 0 ? self.pickerStyle.doneCornerRadius : 6.0f;
_doneBtn.layer.masksToBounds = YES;
}
}
return _doneBtn;
}
#pragma mark - label
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc]initWithFrame:self.pickerStyle.titleLabelFrame];
_titleLabel.backgroundColor = self.pickerStyle.titleLabelColor;
_titleLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
_titleLabel.textAlignment = NSTextAlignmentCenter;
_titleLabel.font = self.pickerStyle.titleTextFont;
_titleLabel.textColor = self.pickerStyle.titleTextColor;
_titleLabel.text = self.title;
}
return _titleLabel;
}
#pragma mark -
- (void)didTapMaskView:(UITapGestureRecognizer *)sender {
[self removePickerFromView:nil];
if (self.cancelBlock) {
self.cancelBlock();
}
}
#pragma mark -
- (void)clickCancelBtn {
[self removePickerFromView:nil];
if (self.cancelBlock) {
self.cancelBlock();
}
}
#pragma mark -
- (void)clickDoneBtn {
[self removePickerFromView:nil];
if (self.doneBlock) {
self.doneBlock();
}
}
#pragma mark -
- (void)addPickerToView:(UIView *)view {
if (view) {
self.frame = view.bounds;
self.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
CGFloat accessoryViewHeight = 0;
if (self.pickerHeaderView) {
CGRect rect = self.pickerHeaderView.frame;
self.pickerHeaderView.frame = CGRectMake(0, 0, view.bounds.size.width, rect.size.height);
self.pickerHeaderView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self addSubview:self.pickerHeaderView];
accessoryViewHeight += self.pickerHeaderView.bounds.size.height;
}
if (self.pickerFooterView) {
CGRect rect = self.pickerFooterView.frame;
self.pickerFooterView.frame = CGRectMake(0, view.bounds.size.height - rect.size.height, view.bounds.size.width, rect.size.height);
self.pickerFooterView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self addSubview:self.pickerFooterView];
accessoryViewHeight += self.pickerFooterView.bounds.size.height;
}
[view addSubview:self];
} else {
[self initUI];
if (self.pickerHeaderView) {
CGRect rect = self.pickerHeaderView.frame;
CGFloat titleBarHeight = self.pickerStyle.hiddenTitleBarView ? 0 : self.pickerStyle.titleBarHeight;
self.pickerHeaderView.frame = CGRectMake(0, titleBarHeight, self.alertView.bounds.size.width, rect.size.height);
self.pickerHeaderView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.alertView addSubview:self.pickerHeaderView];
}
if (self.pickerFooterView) {
CGRect rect = self.pickerFooterView.frame;
self.pickerFooterView.frame = CGRectMake(0, self.alertView.bounds.size.height - self.pickerStyle.paddingBottom - rect.size.height, self.alertView.bounds.size.width, rect.size.height);
self.pickerFooterView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.alertView addSubview:self.pickerFooterView];
}
[self.keyView addSubview:self];
// iOS16 alertView frame
CGFloat accessoryViewHeight = 0;
if (self.pickerHeaderView) {
accessoryViewHeight += self.pickerHeaderView.bounds.size.height;
}
if (self.pickerFooterView) {
accessoryViewHeight += self.pickerFooterView.bounds.size.height;
}
CGFloat height = self.pickerStyle.titleBarHeight + self.pickerStyle.pickerHeight + self.pickerStyle.paddingBottom + accessoryViewHeight;
self.alertView.frame = CGRectMake(0, self.keyView.bounds.size.height - height, self.keyView.bounds.size.width, height);
//
CGRect rect = self.alertView.frame;
rect.origin.y = self.bounds.size.height;
self.alertView.frame = rect;
//
if (!self.pickerStyle.hiddenMaskView) {
self.maskView.alpha = 0;
}
[UIView animateWithDuration:0.3f animations:^{
if (!self.pickerStyle.hiddenMaskView) {
self.maskView.alpha = 1;
}
CGFloat alertViewHeight = self.alertView.bounds.size.height;
CGRect rect = self.alertView.frame;
rect.origin.y -= alertViewHeight;
self.alertView.frame = rect;
}];
}
}
#pragma mark -
- (void)removePickerFromView:(UIView *)view {
if (view) {
[self removeFromSuperview];
} else {
//
[UIView animateWithDuration:0.2f animations:^{
CGFloat alertViewHeight = self.alertView.bounds.size.height;
CGRect rect = self.alertView.frame;
rect.origin.y += alertViewHeight;
self.alertView.frame = rect;
if (!self.pickerStyle.hiddenMaskView) {
self.maskView.alpha = 0;
}
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
}
#pragma mark -
- (void)reloadData {
}
#pragma mark - picker
- (void)addSubViewToPicker:(UIView *)customView {
}
#pragma mark - titleBar
- (void)addSubViewToTitleBar:(UIView *)customView {
if (!self.pickerStyle.hiddenTitleBarView) {
[self.titleBarView addSubview:customView];
}
}
- (BRPickerStyle *)pickerStyle {
if (!_pickerStyle) {
_pickerStyle = [[BRPickerStyle alloc]init];
}
return _pickerStyle;
}
- (UIView *)keyView {
if (!_keyView) {
_keyView = BRGetKeyWindow();
}
return _keyView;
}
#pragma mark - setter
- (void)setTitle:(NSString *)title {
_title = title;
if (_titleLabel) {
_titleLabel.text = title;
}
}
- (void)dealloc {
NSLog(@"%@ dealloc", NSStringFromClass([self class]));
}
@end

View File

@@ -0,0 +1,251 @@
//
// BRPickerStyle.h
// BRPickerViewDemo
//
// Created by renbo on 2019/10/2.
// Copyright © 2019 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "BRPickerViewMacro.h"
NS_ASSUME_NONNULL_BEGIN
// 边框样式(左边取消按钮/右边确定按钮)
typedef NS_ENUM(NSInteger, BRBorderStyle) {
/** 无边框(默认) */
BRBorderStyleNone = 0,
/** 有圆角和边框 */
BRBorderStyleSolid,
/** 仅有圆角 */
BRBorderStyleFill
};
@interface BRPickerStyle : NSObject
/////////////////////////////// 蒙层视图maskView///////////////////////////////
/** 设置背景颜色 */
@property (nullable, nonatomic, strong) UIColor *maskColor;
/** 隐藏 maskView默认为 NO */
@property (nonatomic, assign) BOOL hiddenMaskView;
////////////////////////////// 弹框视图alertView///////////////////////////////
/** 设置 alertView 弹框视图的背景颜色 */
@property (nullable, nonatomic, strong) UIColor *alertViewColor;
/** 设置 alertView 弹框视图左上和右上的圆角半径 */
@property (nonatomic, assign) NSInteger topCornerRadius;
/** 设置 alertView 弹框视图顶部边框线颜色 */
@property (nullable, nonatomic, strong) UIColor *shadowLineColor;
/** 设置 alertView 弹框视图顶部边框线高度 */
@property (nonatomic, assign) CGFloat shadowLineHeight;
/** 隐藏 alertView 弹框视图顶部边框线,默认为 NO */
@property (nonatomic, assign) BOOL hiddenShadowLine;
/** 设置 alertView 弹框视图底部内边距,默认为安全区域底部距屏幕底部的高度 */
@property (nonatomic, assign) CGFloat paddingBottom;
//////////////////////////// 标题栏视图titleBarView ////////////////////////////
/** 设置 titleBarView 标题栏的背景颜色 */
@property (nullable, nonatomic, strong) UIColor *titleBarColor;
/** 设置 titleBarView 标题栏的高度 */
@property (nonatomic, assign) CGFloat titleBarHeight;
/** 设置 titleBarView 标题栏底部分割线颜色 */
@property (nullable, nonatomic, strong) UIColor *titleLineColor;
/** 隐藏 titleBarView 标题栏底部分割线,默认为 NO */
@property (nonatomic, assign) BOOL hiddenTitleLine;
/** 隐藏 titleBarView默认为 NO */
@property (nonatomic, assign) BOOL hiddenTitleBarView;
////////////////////////// 标题栏中间labeltitleLabel///////////////////////////
/** 设置 titleLabel 的背景颜色 */
@property (nullable, nonatomic, strong) UIColor *titleLabelColor;
/** 设置 titleLabel 文本颜色 */
@property (nullable, nonatomic, strong) UIColor *titleTextColor;
/** 设置 titleLabel 字体大小 */
@property (nullable, nonatomic, strong) UIFont *titleTextFont;
/** 设置 titleLabel 的 frame */
@property (nonatomic, assign) CGRect titleLabelFrame;
/** 隐藏 titleLabel默认为 NO */
@property (nonatomic, assign) BOOL hiddenTitleLabel;
/////////////////////////////// 取消按钮cancelBtn//////////////////////////////
/** 设置 cancelBtn 的背景颜色 */
@property (nullable, nonatomic, strong) UIColor *cancelColor;
/** 设置 cancelBtn 标题的颜色 */
@property (nullable, nonatomic, strong) UIColor *cancelTextColor;
/** 设置 cancelBtn 标题的字体 */
@property (nullable, nonatomic, strong) UIFont *cancelTextFont;
/** 设置 cancelBtn 的 frame */
@property (nonatomic, assign) CGRect cancelBtnFrame;
/** 设置 cancelBtn 的边框样式 */
@property (nonatomic, assign) BRBorderStyle cancelBorderStyle;
/** 设置 cancelBtn 的圆角大小 */
@property (nonatomic, assign) CGFloat cancelCornerRadius;
/** 设置 cancelBtn 的边框宽度 */
@property (nonatomic, assign) CGFloat cancelBorderWidth;
/** 设置 cancelBtn 的 image */
@property (nullable, nonatomic, strong) UIImage *cancelBtnImage;
/** 设置 cancelBtn 的 title */
@property (nullable, nonatomic, copy) NSString *cancelBtnTitle;
/** 隐藏 cancelBtn默认为 NO */
@property (nonatomic, assign) BOOL hiddenCancelBtn;
/////////////////////////////// 确定按钮doneBtn////////////////////////////////
/** 设置 doneBtn 的背景颜色 */
@property (nullable, nonatomic, strong) UIColor *doneColor;
/** 设置 doneBtn 标题的颜色 */
@property (nullable, nonatomic, strong) UIColor *doneTextColor;
/** 设置 doneBtn 标题的字体 */
@property (nullable, nonatomic, strong) UIFont *doneTextFont;
/** 设置 doneBtn 的 frame */
@property (nonatomic, assign) CGRect doneBtnFrame;
/** 设置 doneBtn 的边框样式 */
@property (nonatomic, assign) BRBorderStyle doneBorderStyle;
/** 设置 doneBtn 的圆角大小 */
@property (nonatomic, assign) CGFloat doneCornerRadius;
/** 设置 doneBtn 的边框宽度 */
@property (nonatomic, assign) CGFloat doneBorderWidth;
/** 设置 doneBtn 的 image */
@property (nullable, nonatomic, strong) UIImage *doneBtnImage;
/** 设置 doneBtn 的 title */
@property (nullable, nonatomic, copy) NSString *doneBtnTitle;
/** 隐藏 doneBtn默认为 NO */
@property (nonatomic, assign) BOOL hiddenDoneBtn;
/////////////////////////////// 选择器pickerView///////////////////////////////
/** 设置 picker 的背景颜色 */
@property (nullable, nonatomic, strong) UIColor *pickerColor;
/** 设置 picker 中间两条分割线的背景颜色。暂不支持日期选择器前4种类型 */
@property (nullable, nonatomic, strong) UIColor *separatorColor;
/** 设置 picker 中间两条分割线的高度。暂不支持日期选择器前4种类型 */
@property (nonatomic, assign) CGFloat separatorHeight;
/** 设置 picker 文本的颜色。暂不支持日期选择器前4种类型 */
@property (nullable, nonatomic, strong) UIColor *pickerTextColor;
/** 设置 picker 文本的字体。暂不支持日期选择器前4种类型 */
@property (nullable, nonatomic, strong) UIFont *pickerTextFont;
/** 设置 picker 中间选中行的背景颜色。暂不支持日期选择器前4种类型 */
@property (nullable, nonatomic, strong) UIColor *selectRowColor;
/** 设置 picker 中间选中行文本的颜色。暂不支持日期选择器前4种类型 */
@property (nullable, nonatomic, strong) UIColor *selectRowTextColor;
/** 设置 picker 中间选中行文本的字体。暂不支持日期选择器前4种类型 */
@property (nullable, nonatomic, strong) UIFont *selectRowTextFont;
/** 设置 picker 的高度,系统默认高度为 216 */
@property (nonatomic, assign) CGFloat pickerHeight;
/** 设置 picker 的行高。暂不支持日期选择器前4种类型 */
@property (nonatomic, assign) CGFloat rowHeight;
/**
* 清除iOS14之后选择器默认自带的新样式。暂不支持日期选择器前4种类型
* 主要是①隐藏中间选择行的背景样式②清除默认的内边距③新增中间选择行的两条分割线与iOS14之前的样式保持一致默认为 YES
*/
@property (nonatomic, assign) BOOL clearPickerNewStyle;
/**
* 设置语言不设置或为nil时将随系统的语言自动改变
* language: zh-Hans简体中文、zh-Hant繁体中文、en英语
*/
@property(nullable, nonatomic, copy) NSString *language;
/////// 日期选择器单位样式showUnitType == BRShowUnitTypeOnlyCenter 时生效。暂不支持日期选择器前4种类型 ///////
/** 设置日期选择器单位文本的颜色 */
@property (nullable, nonatomic, strong) UIColor *dateUnitTextColor;
/** 设置日期选择器单位文本的字体 */
@property (nullable, nonatomic, strong) UIFont *dateUnitTextFont;
/** 设置日期选择器单位 label 的水平方向偏移量 */
@property (nonatomic, assign) CGFloat dateUnitOffsetX;
/** 设置日期选择器单位 label 的竖直方向偏移量 */
@property (nonatomic, assign) CGFloat dateUnitOffsetY;
//////////////////////////////// 常用的几种模板样式 ////////////////////////////////
/// 弹框模板样式1 - 取消/确定按钮圆角样式
/// @param themeColor 主题颜色
+ (instancetype)pickerStyleWithThemeColor:(nullable UIColor *)themeColor;
/// 弹框模板样式2 - 顶部圆角样式 + 完成按钮
/// @param doneTextColor 完成按钮标题的颜色
+ (instancetype)pickerStyleWithDoneTextColor:(nullable UIColor *)doneTextColor;
/// 弹框模板样式3 - 顶部圆角样式 + 图标按钮
/// @param doneBtnImage 完成按钮的 image
+ (instancetype)pickerStyleWithDoneBtnImage:(nullable UIImage *)doneBtnImage;
//////////////////////////////// 以下是组件内部使用的几个封装方法 ////////////////////////////////
/** 设置选择器中间选中行的样式 */
- (void)setupPickerSelectRowStyle:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
/** 添加选择器中间行上下两条分割线iOS14之后系统默认去掉需要手动添加*/
- (void)addSeparatorLineView:(UIView *)pickerView;
/** 设置 view 的部分圆角 */
// corners(枚举类型,可组合使用)UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight | UIRectCornerAllCorners
+ (void)br_setView:(UIView *)view roundingCorners:(UIRectCorner)corners withRadius:(CGFloat)radius;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,494 @@
//
// BRPickerStyle.m
// BRPickerViewDemo
//
// Created by renbo on 2019/10/2.
// Copyright © 2019 irenb. All dones reserved.
//
// https://github.com/91renb/BRPickerView
#import "BRPickerStyle.h"
#import "NSBundle+BRPickerView.h"
//
#define kBRDefaultTextColor BR_RGB_HEX(0x333333, 1.0f)
@implementation BRPickerStyle
- (instancetype)init {
if (self = [super init]) {
self.clearPickerNewStyle = YES;
}
return self;
}
///
- (UIColor *)maskColor {
if (!_maskColor) {
_maskColor = [self br_colorWithLightColor:BR_RGB_HEX(0x000000, 0.3f) darkColor:BR_RGB_HEX(0x666666, 0.3f)];
}
return _maskColor;
}
- (UIColor *)shadowLineColor {
if (!_shadowLineColor) {
if (@available(iOS 13.0, *)) {
// 线
_shadowLineColor = [UIColor separatorColor];
} else {
_shadowLineColor = BR_RGB_HEX(0xc6c6c8, 1.0f);
}
}
return _shadowLineColor;
}
- (CGFloat)shadowLineHeight {
if (_shadowLineHeight <= 0 || _shadowLineHeight > 5.0f) {
_shadowLineHeight = 0.5f;
}
return _shadowLineHeight;
}
- (CGFloat)paddingBottom {
if (_paddingBottom <= 0) {
_paddingBottom = BR_BOTTOM_MARGIN;
}
return _paddingBottom;
}
- (UIColor *)titleBarColor {
if (!_titleBarColor) {
if (@available(iOS 13.0, *)) {
// #ffffff()#1c1c1e()
_titleBarColor = [UIColor secondarySystemGroupedBackgroundColor];
} else {
_titleBarColor = [UIColor whiteColor];
}
}
return _titleBarColor;
}
- (CGFloat)titleBarHeight {
if (!self.hiddenTitleBarView) {
if (_titleBarHeight < 44.0f && (!self.hiddenCancelBtn || !self.hiddenDoneBtn || !self.hiddenTitleLabel)) {
_titleBarHeight = 44.0f;
}
} else {
_titleBarHeight = 0;
}
return _titleBarHeight;
}
- (UIColor *)titleLineColor {
if (!_titleLineColor) {
_titleLineColor = [self br_colorWithLightColor:BR_RGB_HEX(0xededee, 1.0f) darkColor:BR_RGB_HEX(0x18181c, 1.0f)];
}
return _titleLineColor;
}
- (UIColor *)cancelColor {
if (!_cancelColor) {
_cancelColor = [UIColor clearColor];
}
return _cancelColor;
}
- (UIColor *)cancelTextColor {
if (!_cancelTextColor) {
if (@available(iOS 13.0, *)) {
_cancelTextColor = [UIColor labelColor];
} else {
_cancelTextColor = kBRDefaultTextColor;
}
}
return _cancelTextColor;
}
- (UIFont *)cancelTextFont {
if (!_cancelTextFont) {
_cancelTextFont = [UIFont systemFontOfSize:16.0f];
}
return _cancelTextFont;
}
- (NSString *)cancelBtnTitle {
if (!_cancelBtnTitle && !_cancelBtnImage) {
_cancelBtnTitle = [NSBundle br_localizedStringForKey:@"取消" language:self.language];
}
return _cancelBtnTitle;
}
- (CGRect)cancelBtnFrame {
if (CGRectEqualToRect(_cancelBtnFrame, CGRectZero) || _cancelBtnFrame.size.height == 0) {
_cancelBtnFrame = CGRectMake(5, 8, 60, 28);
}
return _cancelBtnFrame;
}
- (UIColor *)titleLabelColor {
if (!_titleLabelColor) {
_titleLabelColor = [UIColor clearColor];
}
return _titleLabelColor;
}
- (UIColor *)titleTextColor {
if (!_titleTextColor) {
if (@available(iOS 13.0, *)) {
_titleTextColor = [UIColor secondaryLabelColor];
} else {
_titleTextColor = BR_RGB_HEX(0x999999, 1.0f);
}
}
return _titleTextColor;
}
- (UIFont *)titleTextFont {
if (!_titleTextFont) {
_titleTextFont = [UIFont systemFontOfSize:15.0f];
}
return _titleTextFont;
}
- (CGRect)titleLabelFrame {
if (CGRectEqualToRect(_titleLabelFrame, CGRectZero) || _titleLabelFrame.size.height == 0) {
_titleLabelFrame = CGRectMake(5 + 60 + 2, 0, BRGetKeyWindow().bounds.size.width - 2 * (5 + 60 + 2), 44);
}
return _titleLabelFrame;
}
- (UIColor *)doneColor {
if (!_doneColor) {
_doneColor = [UIColor clearColor];
}
return _doneColor;
}
- (UIColor *)doneTextColor {
if (!_doneTextColor) {
if (@available(iOS 13.0, *)) {
_doneTextColor = [UIColor labelColor];
} else {
_doneTextColor = kBRDefaultTextColor;
}
}
return _doneTextColor;
}
- (UIFont *)doneTextFont {
if (!_doneTextFont) {
_doneTextFont = [UIFont systemFontOfSize:16.0f];
}
return _doneTextFont;
}
- (NSString *)doneBtnTitle {
if (!_doneBtnTitle && !_doneBtnImage) {
_doneBtnTitle = [NSBundle br_localizedStringForKey:@"确定" language:self.language];
}
return _doneBtnTitle;
}
- (CGRect)doneBtnFrame {
if (CGRectEqualToRect(_doneBtnFrame, CGRectZero) || _doneBtnFrame.size.height == 0) {
_doneBtnFrame = CGRectMake(BRGetKeyWindow().bounds.size.width - 60 - 5, 8, 60, 28);
}
return _doneBtnFrame;
}
- (UIColor *)pickerColor {
if (!_pickerColor) {
if (@available(iOS 13.0, *)) {
// #ffffff()#1c1c1e()
_pickerColor = [UIColor secondarySystemGroupedBackgroundColor];
} else {
_pickerColor = [UIColor whiteColor];
}
}
return _pickerColor;
}
- (UIColor *)separatorColor {
if (!_separatorColor) {
if (@available(iOS 13.0, *)) {
// 线
_separatorColor = [UIColor opaqueSeparatorColor];
} else {
_separatorColor = BR_RGB_HEX(0xc6c6c8, 1.0f);
}
}
return _separatorColor;
}
- (UIColor *)pickerTextColor {
if (!_pickerTextColor) {
if (@available(iOS 13.0, *)) {
_pickerTextColor = [UIColor labelColor];
} else {
_pickerTextColor = kBRDefaultTextColor;
}
}
return _pickerTextColor;
}
- (UIFont *)pickerTextFont {
if (!_pickerTextFont) {
_pickerTextFont = [UIFont systemFontOfSize:18.0f];
}
return _pickerTextFont;
}
- (CGFloat)pickerHeight {
if (_pickerHeight < 40) {
_pickerHeight = 216.0f;
}
return _pickerHeight;
}
- (CGFloat)rowHeight {
if (_rowHeight < 20) {
_rowHeight = 35.0f;
}
return _rowHeight;
}
- (NSString *)language {
if (!_language) {
//
// zh-Hans-CN()zh-Hant-CN()en-CN()en-GB()
// `CN`iOS9CN US
_language = [NSLocale preferredLanguages].firstObject;
}
return _language;
}
- (UIColor *)dateUnitTextColor {
if (!_dateUnitTextColor) {
if (@available(iOS 13.0, *)) {
_dateUnitTextColor = [UIColor labelColor];
} else {
_dateUnitTextColor = kBRDefaultTextColor;
}
}
return _dateUnitTextColor;
}
- (UIFont *)dateUnitTextFont {
if (!_dateUnitTextFont) {
_dateUnitTextFont = [UIFont systemFontOfSize:18.0f];
}
return _dateUnitTextFont;
}
#pragma mark -
- (UIColor *)br_colorWithLightColor:(UIColor *)lightColor darkColor:(UIColor *)darkColor {
if (@available(iOS 13.0, *)) {
UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
if ([traitCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
return lightColor;
} else {
return darkColor;
}
}];
return dyColor;
} else {
return lightColor;
}
}
#pragma mark - 1 - /
+ (instancetype)pickerStyleWithThemeColor:(UIColor *)themeColor {
BRPickerStyle *customStyle = [[self alloc]init];
if (themeColor) {
customStyle.cancelTextColor = themeColor;
customStyle.cancelBorderStyle = BRBorderStyleSolid;
customStyle.doneColor = themeColor;
customStyle.doneTextColor = [UIColor whiteColor];
customStyle.doneBorderStyle = BRBorderStyleFill;
}
return customStyle;
}
#pragma mark - 2 - +
+ (instancetype)pickerStyleWithDoneTextColor:(UIColor *)doneTextColor {
BRPickerStyle *customStyle = [[self alloc]init];
if (doneTextColor) {
customStyle.topCornerRadius = 16.0f;
customStyle.hiddenCancelBtn = YES;
customStyle.hiddenTitleLine = YES;
customStyle.titleLabelFrame = CGRectMake(20, 4, 100, 40);
customStyle.doneTextColor = doneTextColor;
customStyle.doneTextFont = [UIFont boldSystemFontOfSize:18.0f];
customStyle.doneBtnFrame = CGRectMake(BRGetKeyWindow().bounds.size.width - 60, 4, 60, 40);
customStyle.doneBtnTitle = [NSBundle br_localizedStringForKey:@"完成" language:customStyle.language];
customStyle.selectRowTextColor = doneTextColor;
customStyle.selectRowTextFont = [UIFont boldSystemFontOfSize:20.0f];
}
return customStyle;
}
#pragma mark - 3 - +
+ (instancetype)pickerStyleWithDoneBtnImage:(UIImage *)doneBtnImage {
BRPickerStyle *customStyle = [[self alloc]init];
if (doneBtnImage) {
customStyle.topCornerRadius = 16.0f;
customStyle.hiddenTitleLine = YES;
customStyle.hiddenCancelBtn = YES;
customStyle.titleLabelFrame = CGRectMake(20, 4, 100, 40);
customStyle.doneBtnImage = doneBtnImage;
customStyle.doneBtnFrame = CGRectMake(BRGetKeyWindow().bounds.size.width - 44, 4, 40, 40);
}
return customStyle;
}
#pragma mark -
- (void)setupPickerSelectRowStyle:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
// 1.线
NSString *systemVersion = [UIDevice currentDevice].systemVersion;
if (systemVersion.doubleValue < 14.0) {
for (UIView *subView in pickerView.subviews) {
if (subView && [subView isKindOfClass:[UIView class]] && subView.frame.size.height <= 1) {
subView.backgroundColor = self.separatorColor;
// 线
if (self.separatorHeight > 0) {
CGRect rect = subView.frame;
rect.size.height = self.separatorHeight;
subView.frame = rect;
}
}
}
}
// 2.
UIView *contentView = nil;
NSArray *subviews = pickerView.subviews;
if (subviews.count > 0) {
id firstView = subviews.firstObject;
if (firstView && [firstView isKindOfClass:[UIView class]]) {
contentView = (UIView *)firstView;
}
}
if (self.selectRowColor) {
UIView *columnView = nil;
if (contentView) {
id obj = [contentView valueForKey:@"subviewCache"];
if (obj && [obj isKindOfClass:[NSArray class]]) {
NSArray *columnViews = (NSArray *)obj;
if (columnViews.count > 0) {
id columnObj = columnViews.firstObject;
if (columnObj && [columnObj isKindOfClass:[UIView class]]) {
columnView = (UIView *)columnObj;
}
}
}
}
if (columnView) {
id obj = [columnView valueForKey:@"middleContainerView"];
if (obj && [obj isKindOfClass:[UIView class]]) {
UIView *selectRowView = (UIView *)obj;
//
selectRowView.backgroundColor = self.selectRowColor;
}
}
}
if (contentView && self.clearPickerNewStyle) {
if (systemVersion.doubleValue >= 14.0) {
//
id lastView = subviews.lastObject;
if (lastView && [lastView isKindOfClass:[UIView class]]) {
UIView *rectBgView = (UIView *)lastView;
rectBgView.hidden = YES;
}
// iOS14
if (systemVersion.doubleValue < 15.0f) {
[self setPickerAllSubViewsStyle:contentView];
}
}
}
// 3./
if (self.selectRowTextColor || self.selectRowTextFont) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// label
UILabel *selectLabel = (UILabel *)[pickerView viewForRow:row forComponent:component];
if (selectLabel) {
if (self.selectRowTextColor) {
selectLabel.textColor = self.selectRowTextColor;
}
if (self.selectRowTextFont) {
selectLabel.font = self.selectRowTextFont;
}
}
});
}
}
// frame iOS14 UIPickerView
- (void)setPickerAllSubViewsStyle:(UIView *)view {
NSArray *subViews = view.subviews;
if (subViews.count == 0 || [view isKindOfClass:[UILabel class]]) return;
for (UIView *subView in subViews) {
NSString *className = NSStringFromClass([subView class]);
if ([className isEqualToString:@"UIPickerColumnView"]) {
CGRect rect = subView.frame;
rect.origin.x = 0;
rect.size.width = view.bounds.size.width;
subView.frame = rect;
}
NSString *superClassName = NSStringFromClass([view class]);
if ([superClassName isEqualToString:@"UIPickerColumnView"]) {
CGRect rect = subView.frame;
rect.size.width = view.bounds.size.width;
subView.frame = rect;
}
if ([subView isKindOfClass:[UILabel class]]) {
CGRect rect = subView.frame;
rect.origin.x = 10;
subView.frame = rect;
}
[self setPickerAllSubViewsStyle:subView];
}
}
#pragma mark - 线iOS14
- (void)addSeparatorLineView:(UIView *)pickerView {
if ([UIDevice currentDevice].systemVersion.doubleValue >= 14.0) {
UIView *topLineView = [[UIView alloc]initWithFrame:CGRectMake(0, pickerView.bounds.size.height / 2 - self.rowHeight / 2, pickerView.bounds.size.width, 0.5f)];
topLineView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
topLineView.backgroundColor = self.separatorColor;
// 线
if (self.separatorHeight > 0) {
CGRect topRect = topLineView.frame;
topRect.size.height = self.separatorHeight;
topLineView.frame = topRect;
}
[pickerView addSubview:topLineView];
UIView *bottomLineView = [[UIView alloc]initWithFrame:CGRectMake(0, pickerView.bounds.size.height / 2 + self.rowHeight / 2, pickerView.bounds.size.width, 0.5f)];
bottomLineView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
bottomLineView.backgroundColor = self.separatorColor;
// 线
if (self.separatorHeight > 0) {
CGRect bottomRect = bottomLineView.frame;
bottomRect.size.height = self.separatorHeight;
bottomLineView.frame = bottomRect;
}
[pickerView addSubview:bottomLineView];
}
}
#pragma mark - view
// corners(使)UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight | UIRectCornerAllCorners
+ (void)br_setView:(UIView *)view roundingCorners:(UIRectCorner)corners withRadius:(CGFloat)radius {
UIBezierPath *rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *shape = [[CAShapeLayer alloc]init];
[shape setPath:rounded.CGPath];
view.layer.mask = shape;
}
@end

View File

@@ -0,0 +1,35 @@
/*
Localizable.strings
BRPickerViewDemo
Created by renbo on 2019/10/30.
Copyright © 2019 irenb. All rights reserved.
*/
"确定" = "OK";
"取消" = "Cancel";
"完成" = "Done";
"年" = " ";
"月" = " ";
"日" = " ";
"时" = " ";
"分" = " ";
"秒" = " ";
"周" = " ";
"季度" = " ";
"上午" = "AM";
"下午" = "PM";
"至今" = " Now";
"今天" = " Today";
"周一" = " Mon";
"周二" = " Tue";
"周三" = " Wed";
"周四" = " Thu";
"周五" = " Fri";
"周六" = " Sat";
"周日" = " Sun";

View File

@@ -0,0 +1,35 @@
/*
Localizable.strings
BRPickerViewDemo
Created by renbo on 2019/10/30.
Copyright © 2019 irenb. All rights reserved.
*/
"确定" = "确定";
"取消" = "取消";
"完成" = "完成";
"年" = "年";
"月" = "月";
"日" = "日";
"时" = "时";
"分" = "分";
"秒" = "秒";
"周" = "周";
"季度" = "季度";
"上午" = "上午";
"下午" = "下午";
"至今" = "至今";
"今天" = "今天";
"周一" = "周一";
"周二" = "周二";
"周三" = "周三";
"周四" = "周四";
"周五" = "周五";
"周六" = "周六";
"周日" = "周日";

View File

@@ -0,0 +1,35 @@
/*
Localizable.strings
BRPickerViewDemo
Created by renbo on 2019/10/30.
Copyright © 2019 irenb. All rights reserved.
*/
"确定" = "確定";
"取消" = "取消";
"完成" = "完成";
"年" = "年";
"月" = "月";
"日" = "日";
"时" = "時";
"分" = "分";
"秒" = "秒";
"周" = "周";
"季度" = "季度";
"上午" = "上午";
"下午" = "下午";
"至今" = "至今";
"今天" = "今天";
"周一" = "周壹";
"周二" = "周二";
"周三" = "周三";
"周四" = "周四";
"周五" = "周五";
"周六" = "周六";
"周日" = "周日";

View File

@@ -0,0 +1,87 @@
//
// BRPickerViewMacro.h
// BRPickerViewDemo
//
// Created by renbo on 2018/4/23.
// Copyright © 2018 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#ifndef BRPickerViewMacro_h
#define BRPickerViewMacro_h
#import <UIKit/UIKit.h>
// 屏幕安全区域下边距
#define BR_BOTTOM_MARGIN \
({CGFloat safeBottomHeight = 0;\
if (@available(iOS 11.0, *)) {\
safeBottomHeight = BRGetKeyWindow().safeAreaInsets.bottom;\
}\
(safeBottomHeight);})
// 静态库中编写 Category 时的便利宏,用于解决 Category 方法从静态库中加载需要特别设置的问题
#ifndef BRSYNTH_DUMMY_CLASS
#define BRSYNTH_DUMMY_CLASS(_name_) \
@interface BRSYNTH_DUMMY_CLASS_ ## _name_ : NSObject @end \
@implementation BRSYNTH_DUMMY_CLASS_ ## _name_ @end
#endif
// 打印错误日志
#ifdef DEBUG
#define BRErrorLog(...) NSLog(@"reason: %@", [NSString stringWithFormat:__VA_ARGS__])
#else
#define BRErrorLog(...)
#endif
/** RGB颜色(16进制) */
static inline UIColor *BR_RGB_HEX(uint32_t rgbValue, CGFloat alpha) {
return [UIColor colorWithRed:((CGFloat)((rgbValue & 0xFF0000) >> 16)) / 255.0
green:((CGFloat)((rgbValue & 0xFF00) >> 8)) / 255.0
blue:((CGFloat)(rgbValue & 0xFF)) / 255.0
alpha:(alpha)];
}
/** 获取 keyWindow */
static inline UIWindow *BRGetKeyWindow(void) {
UIWindow *keyWindow = nil;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 // 编译时检查SDK版本兼容不同版本的Xcode防止编译报错
if (@available(iOS 13.0, *)) { // 运行时检查系统版本(兼容不同版本的系统,防止运行报错)
NSSet<UIScene *> *connectedScenes = [UIApplication sharedApplication].connectedScenes;
for (UIScene *scene in connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
for (UIWindow *window in windowScene.windows) {
if (window.isKeyWindow) {
keyWindow = window;
break;
}
}
}
}
}
#endif
if (!keyWindow) {
keyWindow = [UIApplication sharedApplication].windows.firstObject;
if (!keyWindow.isKeyWindow) {
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
UIWindow *window = [UIApplication sharedApplication].keyWindow;
if (CGRectEqualToRect(window.bounds, UIScreen.mainScreen.bounds)) {
keyWindow = window;
}
#endif
}
}
return keyWindow;
}
#endif /* BRPickerViewMacro_h */

View File

@@ -0,0 +1,26 @@
//
// NSBundle+BRPickerView.h
// BRPickerViewDemo
//
// Created by renbo on 2019/10/30.
// Copyright © 2019 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSBundle (BRPickerView)
/// 获取 BRPickerView.bundle
+ (instancetype)br_pickerBundle;
/// 获取国际化后的文本
/// @param key 代表 Localizable.strings 文件中 key-value 中的 key。
/// @param language 设置语言可为空为nil时将随系统的语言自动改变
+ (NSString *)br_localizedStringForKey:(NSString *)key language:(NSString *)language;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,68 @@
//
// NSBundle+BRPickerView.m
// BRPickerViewDemo
//
// Created by renbo on 2019/10/30.
// Copyright © 2019 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "NSBundle+BRPickerView.h"
#import "BRBaseView.h"
BRSYNTH_DUMMY_CLASS(NSBundle_BRPickerView)
@implementation NSBundle (BRPickerView)
#pragma mark - BRPickerView.bundle
+ (instancetype)br_pickerBundle {
static NSBundle *pickerBundle = nil;
if (!pickerBundle) {
/*
bundle
framework framework bundle
target client main bundle
BRPickerView bundle
*/
NSBundle *bundle = [NSBundle bundleForClass:[BRBaseView class]];
NSURL *url = [bundle URLForResource:@"BRPickerView" withExtension:@"bundle"];
pickerBundle = [NSBundle bundleWithURL:url];
}
return pickerBundle;
}
#pragma mark -
+ (NSString *)br_localizedStringForKey:(NSString *)key language:(NSString *)language {
return [self br_localizedStringForKey:key value:nil language:language];
}
+ (NSString *)br_localizedStringForKey:(NSString *)key value:(NSString *)value language:(NSString *)language {
static NSBundle *bundle = nil;
if (!bundle) {
//
if (!language) {
//
language = [NSLocale preferredLanguages].firstObject;
}
if ([language hasPrefix:@"en"]) {
language = @"en";
} else if ([language hasPrefix:@"zh"]) {
if ([language rangeOfString:@"Hans"].location != NSNotFound) {
language = @"zh-Hans"; //
} else { // zh-Hantzh-HKzh-TW
language = @"zh-Hant"; //
}
} else {
language = @"en";
}
// BRPickerView.bundle
bundle = [NSBundle bundleWithPath:[[self br_pickerBundle] pathForResource:language ofType:@"lproj"]];
}
value = [bundle localizedStringForKey:key value:value table:nil];
return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil];
}
@end

View File

@@ -0,0 +1,111 @@
//
// BRDatePickerView+BR.h
// BRPickerViewDemo
//
// Created by renbo on 2020/6/16.
// Copyright © 2020 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import "BRDatePickerView.h"
NS_ASSUME_NONNULL_BEGIN
@interface BRDatePickerView (BR)
/** 最小日期 */
- (NSDate *)handlerMinDate:(nullable NSDate *)minDate;
/** 最大日期 */
- (NSDate *)handlerMaxDate:(nullable NSDate *)maxDate;
/** 默认选中的日期 */
- (NSDate *)handlerSelectDate:(nullable NSDate *)selectDate dateFormat:(NSString *)dateFormat;
/** NSDate 转 NSString */
- (NSString *)br_stringFromDate:(NSDate *)date dateFormat:(NSString *)dateFormat;
/** NSString 转 NSDate */
- (NSDate *)br_dateFromString:(NSString *)dateString dateFormat:(NSString *)dateFormat;
/** 比较两个日期大小(可以指定比较级数,即按指定格式进行比较) */
- (NSComparisonResult)br_compareDate:(NSDate *)date targetDate:(NSDate *)targetDate dateFormat:(NSString *)dateFormat;
/** 获取 yearArr 数组 */
- (NSArray *)getYearArr;
/** 获取 monthArr 数组 */
- (NSArray *)getMonthArr:(NSInteger)year;
/** 获取 dayArr 数组 */
- (NSArray *)getDayArr:(NSInteger)year month:(NSInteger)month;
/** 获取 hourArr 数组 */
- (NSArray *)getHourArr:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;
/** 获取 minuteArr 数组 */
- (NSArray *)getMinuteArr:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour;
/** 获取 secondArr 数组 */
- (NSArray *)getSecondArr:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute;
/** 获取 monthWeekArr 数组 */
- (NSArray *)getMonthWeekArr:(NSInteger)year month:(NSInteger)month;
/** 获取 yearWeekArr 数组 */
- (NSArray *)getYearWeekArr:(NSInteger)year;
/** 获取 quarterArr 数组 */
- (NSArray *)getQuarterArr:(NSInteger)year;
/** 添加 pickerView */
- (void)setupPickerView:(UIView *)pickerView toView:(UIView *)view;
/** 设置日期单位 */
- (NSArray *)setupPickerUnitLabel:(UIPickerView *)pickerView unitArr:(NSArray *)unitArr;
- (NSString *)getYearNumber:(NSInteger)year;
- (NSString *)getMDHMSNumber:(NSInteger)number;
- (NSString *)getYearText:(NSArray *)yearArr row:(NSInteger)row;
- (NSString *)getMonthText:(NSArray *)monthArr row:(NSInteger)row;
- (NSString *)getDayText:(NSArray *)dayArr row:(NSInteger)row mSelectDate:(NSDate *)mSelectDate;
- (NSString *)getHourText:(NSArray *)hourArr row:(NSInteger)row;
- (NSString *)getMinuteText:(NSArray *)minuteArr row:(NSInteger)row;
- (NSString *)getSecondText:(NSArray *)secondArr row:(NSInteger)row;
- (NSString *)getWeekText:(NSArray *)weekArr row:(NSInteger)row;
- (NSString *)getQuarterText:(NSArray *)quarterArr row:(NSInteger)row;
- (NSString *)getAMText;
- (NSString *)getPMText;
- (NSString *)getYearUnit;
- (NSString *)getMonthUnit;
- (NSString *)getDayUnit;
- (NSString *)getHourUnit;
- (NSString *)getMinuteUnit;
- (NSString *)getSecondUnit;
- (NSString *)getWeekUnit;
- (NSString *)getQuarterUnit;
- (NSInteger)getIndexWithArray:(NSArray *)array object:(NSString *)obj;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,755 @@
//
// BRDatePickerView+BR.m
// BRPickerViewDemo
//
// Created by renbo on 2020/6/16.
// Copyright © 2020 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "BRDatePickerView+BR.h"
#import "NSBundle+BRPickerView.h"
BRSYNTH_DUMMY_CLASS(BRDatePickerView_BR)
//////////////////////////////////////////
/// BRDatePickerView
//////////////////////////////////////////
@implementation BRDatePickerView (BR)
#pragma mark -
- (NSDate *)handlerMinDate:(NSDate *)minDate {
if (!minDate) {
if (self.pickerMode == BRDatePickerModeMDHM) {
minDate = [NSDate br_setMonth:1 day:1 hour:0 minute:0];
} else if (self.pickerMode == BRDatePickerModeMD) {
minDate = [NSDate br_setMonth:1 day:1];
} else if (self.pickerMode == BRDatePickerModeTime || self.pickerMode == BRDatePickerModeCountDownTimer || self.pickerMode == BRDatePickerModeHM) {
minDate = [NSDate br_setHour:0 minute:0];
} else if (self.pickerMode == BRDatePickerModeHMS) {
minDate = [NSDate br_setHour:0 minute:0 second:0];
} else if (self.pickerMode == BRDatePickerModeMS) {
minDate = [NSDate br_setMinute:0 second:0];
} else {
minDate = [NSDate distantPast]; //
}
}
return minDate;
}
#pragma mark -
- (NSDate *)handlerMaxDate:(NSDate *)maxDate {
if (!maxDate) {
if (self.pickerMode == BRDatePickerModeMDHM) {
maxDate = [NSDate br_setMonth:12 day:31 hour:23 minute:59];
} else if (self.pickerMode == BRDatePickerModeMD) {
maxDate = [NSDate br_setMonth:12 day:31];
} else if (self.pickerMode == BRDatePickerModeTime || self.pickerMode == BRDatePickerModeCountDownTimer || self.pickerMode == BRDatePickerModeHM) {
maxDate = [NSDate br_setHour:23 minute:59];
} else if (self.pickerMode == BRDatePickerModeHMS) {
maxDate = [NSDate br_setHour:23 minute:59 second:59];
} else if (self.pickerMode == BRDatePickerModeMS) {
maxDate = [NSDate br_setMinute:59 second:59];
} else {
maxDate = [NSDate distantFuture]; //
}
}
return maxDate;
}
#pragma mark -
- (NSDate *)handlerSelectDate:(NSDate *)selectDate dateFormat:(NSString *)dateFormat {
// selectDate selectValue使 selectDate
if (!selectDate) {
if (self.selectValue && self.selectValue.length > 0) {
if (self.pickerMode == BRDatePickerModeYMDH && self.isShowAMAndPM) {
NSString *firstString = [[self.selectValue componentsSeparatedByString:@" "] firstObject];
NSString *lastString = [[self.selectValue componentsSeparatedByString:@" "] lastObject];
if ([lastString isEqualToString:[self getAMText]]) {
self.selectValue = [NSString stringWithFormat:@"%@ 00", firstString];
}
if ([lastString isEqualToString:[self getPMText]]) {
self.selectValue = [NSString stringWithFormat:@"%@ 12", firstString];
}
}
NSDate *date = nil;
if ([self.selectValue isEqualToString:self.lastRowContent]) {
date = self.addToNow ? [NSDate date] : nil;
} else if ([self.selectValue isEqualToString:self.firstRowContent]) {
date = nil;
} else {
date = [self br_dateFromString:self.selectValue dateFormat:dateFormat];
if (!date) {
BRErrorLog(@"参数异常!字符串 selectValue 的正确格式是:%@", dateFormat);
NSAssert(date, @"参数异常!请检查字符串 selectValue 的格式");
date = [NSDate date]; // / Release
}
if (self.pickerMode == BRDatePickerModeMDHM) {
selectDate = [NSDate br_setMonth:date.br_month day:date.br_day hour:date.br_hour minute:date.br_minute];
} else if (self.pickerMode == BRDatePickerModeMD) {
selectDate = [NSDate br_setMonth:date.br_month day:date.br_day];
} else if (self.pickerMode == BRDatePickerModeTime || self.pickerMode == BRDatePickerModeCountDownTimer || self.pickerMode == BRDatePickerModeHM) {
selectDate = [NSDate br_setHour:date.br_hour minute:date.br_minute];
} else if (self.pickerMode == BRDatePickerModeHMS) {
selectDate = [NSDate br_setHour:date.br_hour minute:date.br_minute second:date.br_second];
} else if (self.pickerMode == BRDatePickerModeMS) {
selectDate = [NSDate br_setMinute:date.br_minute second:date.br_second];
} else {
selectDate = date;
}
}
} else {
//
if (self.pickerMode == BRDatePickerModeTime ||
self.pickerMode == BRDatePickerModeCountDownTimer ||
self.pickerMode == BRDatePickerModeHM ||
self.pickerMode == BRDatePickerModeHMS ||
self.pickerMode == BRDatePickerModeMS) {
//
selectDate = self.minDate;
} else {
if (self.minuteInterval > 1 || self.secondInterval > 1) {
NSDate *date = [NSDate date];
NSInteger minute = self.minDate.br_minute % self.minuteInterval == 0 ? self.minDate.br_minute : 0;
NSInteger second = self.minDate.br_second % self.secondInterval == 0 ? self.minDate.br_second : 0;
selectDate = [NSDate br_setYear:date.br_year month:date.br_month day:date.br_day hour:date.br_hour minute:minute second:second];
} else {
//
selectDate = [NSDate date];
}
}
}
}
//
BOOL selectLessThanMin = [self br_compareDate:selectDate targetDate:self.minDate dateFormat:dateFormat] == NSOrderedAscending;
BOOL selectMoreThanMax = [self br_compareDate:selectDate targetDate:self.maxDate dateFormat:dateFormat] == NSOrderedDescending;
if (selectLessThanMin) {
BRErrorLog(@"默认选择的日期不能小于最小日期!");
selectDate = self.minDate;
}
if (selectMoreThanMax) {
BRErrorLog(@"默认选择的日期不能大于最大日期!");
selectDate = self.maxDate;
}
return selectDate;
}
#pragma mark - NSDate NSString
- (NSString *)br_stringFromDate:(NSDate *)date dateFormat:(NSString *)dateFormat {
return [NSDate br_stringFromDate:date dateFormat:dateFormat timeZone:self.timeZone language:self.pickerStyle.language];
}
#pragma mark - NSString NSDate
- (NSDate *)br_dateFromString:(NSString *)dateString dateFormat:(NSString *)dateFormat {
return [NSDate br_dateFromString:dateString dateFormat:dateFormat timeZone:self.timeZone language:self.pickerStyle.language];
}
#pragma mark -
- (NSComparisonResult)br_compareDate:(NSDate *)date targetDate:(NSDate *)targetDate dateFormat:(NSString *)dateFormat {
NSString *dateString1 = [self br_stringFromDate:date dateFormat:dateFormat];
NSString *dateString2 = [self br_stringFromDate:targetDate dateFormat:dateFormat];
NSDate *date1 = [self br_dateFromString:dateString1 dateFormat:dateFormat];
NSDate *date2 = [self br_dateFromString:dateString2 dateFormat:dateFormat];
if ([date1 compare:date2] == NSOrderedDescending) {
return 1; //
} else if ([date1 compare:date2] == NSOrderedAscending) {
return -1; //
} else {
return 0; //
}
}
#pragma mark - yearArr
- (NSArray *)getYearArr {
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = self.minDate.br_year; i <= self.maxDate.br_year; i++) {
[tempArr addObject:[self getYearNumber:i]];
}
if (self.isDescending) {
NSArray *reversedArr = [[tempArr reverseObjectEnumerator] allObjects];
tempArr = [reversedArr mutableCopy];
}
//
if (self.lastRowContent || self.firstRowContent) {
switch (self.pickerMode) {
case BRDatePickerModeYMDHMS:
case BRDatePickerModeYMDHM:
case BRDatePickerModeYMDH:
case BRDatePickerModeYMD:
case BRDatePickerModeYM:
case BRDatePickerModeY:
{
if (self.lastRowContent) {
[tempArr addObject:self.lastRowContent];
}
if (self.firstRowContent) {
[tempArr insertObject:self.firstRowContent atIndex:0];
}
}
break;
default:
break;
}
}
return [tempArr copy];
}
#pragma mark - monthArr
- (NSArray *)getMonthArr:(NSInteger)year {
NSInteger startMonth = 1;
NSInteger endMonth = 12;
if (year == self.minDate.br_year) {
startMonth = self.minDate.br_month;
}
if (year == self.maxDate.br_year) {
endMonth = self.maxDate.br_month;
}
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = startMonth; i <= endMonth; i++) {
[tempArr addObject:[self getMDHMSNumber:i]];
}
if (self.isDescending) {
NSArray *reversedArr = [[tempArr reverseObjectEnumerator] allObjects];
tempArr = [reversedArr mutableCopy];
}
//
if (self.lastRowContent || self.firstRowContent) {
switch (self.pickerMode) {
case BRDatePickerModeMDHM:
case BRDatePickerModeMD:
{
if (self.lastRowContent) {
[tempArr addObject:self.lastRowContent];
}
if (self.firstRowContent) {
[tempArr insertObject:self.firstRowContent atIndex:0];
}
}
break;
default:
break;
}
}
return [tempArr copy];
}
#pragma mark - dayArr
- (NSArray *)getDayArr:(NSInteger)year month:(NSInteger)month {
NSInteger startDay = 1;
NSInteger endDay = [NSDate br_getDaysInYear:year month:month];
if (year == self.minDate.br_year && month == self.minDate.br_month) {
startDay = self.minDate.br_day;
}
if (year == self.maxDate.br_year && month == self.maxDate.br_month) {
endDay = self.maxDate.br_day;
}
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = startDay; i <= endDay; i++) {
[tempArr addObject:[self getMDHMSNumber:i]];
}
if (self.isDescending) {
return [[tempArr reverseObjectEnumerator] allObjects];
}
return [tempArr copy];
}
#pragma mark - hourArr
- (NSArray *)getHourArr:(NSInteger)year month:(NSInteger)month day:(NSInteger)day {
if (self.pickerMode == BRDatePickerModeYMDH && self.isShowAMAndPM) {
return @[[self getAMText], [self getPMText]];
}
NSInteger startHour = 0;
NSInteger endHour = 23;
if (year == self.minDate.br_year && month == self.minDate.br_month && day == self.minDate.br_day) {
startHour = self.minDate.br_hour;
}
if (year == self.maxDate.br_year && month == self.maxDate.br_month && day == self.maxDate.br_day) {
endHour = self.maxDate.br_hour;
}
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = startHour; i <= endHour; i++) {
[tempArr addObject:[self getMDHMSNumber:i]];
}
if (self.isDescending) {
NSArray *reversedArr = [[tempArr reverseObjectEnumerator] allObjects];
tempArr = [reversedArr mutableCopy];
}
//
if (self.lastRowContent || self.firstRowContent) {
switch (self.pickerMode) {
case BRDatePickerModeHMS:
case BRDatePickerModeHM:
{
if (self.lastRowContent) {
[tempArr addObject:self.lastRowContent];
}
if (self.firstRowContent) {
[tempArr insertObject:self.firstRowContent atIndex:0];
}
}
break;
default:
break;
}
}
return [tempArr copy];
}
#pragma mark - minuteArr
- (NSArray *)getMinuteArr:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour {
NSInteger startMinute = 0;
NSInteger endMinute = 59;
if (year == self.minDate.br_year && month == self.minDate.br_month && day == self.minDate.br_day && hour == self.minDate.br_hour) {
startMinute = self.minDate.br_minute;
}
if (year == self.maxDate.br_year && month == self.maxDate.br_month && day == self.maxDate.br_day && hour == self.maxDate.br_hour) {
endMinute = self.maxDate.br_minute;
}
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = startMinute; i <= endMinute; i += self.minuteInterval) {
[tempArr addObject:[self getMDHMSNumber:i]];
}
if (self.isDescending) {
NSArray *reversedArr = [[tempArr reverseObjectEnumerator] allObjects];
tempArr = [reversedArr mutableCopy];
}
//
if (self.lastRowContent || self.firstRowContent) {
switch (self.pickerMode) {
case BRDatePickerModeMS:
{
if (self.lastRowContent) {
[tempArr addObject:self.lastRowContent];
}
if (self.firstRowContent) {
[tempArr insertObject:self.firstRowContent atIndex:0];
}
}
break;
default:
break;
}
}
return [tempArr copy];
}
#pragma mark - secondArr
- (NSArray *)getSecondArr:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute {
NSInteger startSecond = 0;
NSInteger endSecond = 59;
if (year == self.minDate.br_year && month == self.minDate.br_month && day == self.minDate.br_day && hour == self.minDate.br_hour && minute == self.minDate.br_minute) {
startSecond = self.minDate.br_second;
}
if (year == self.maxDate.br_year && month == self.maxDate.br_month && day == self.maxDate.br_day && hour == self.maxDate.br_hour && minute == self.maxDate.br_minute) {
endSecond = self.maxDate.br_second;
}
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = startSecond; i <= endSecond; i += self.secondInterval) {
[tempArr addObject:[self getMDHMSNumber:i]];
}
if (self.isDescending) {
return [[tempArr reverseObjectEnumerator] allObjects];
}
return [tempArr copy];
}
#pragma mark - monthWeekArr
- (NSArray *)getMonthWeekArr:(NSInteger)year month:(NSInteger)month {
NSInteger startWeek = 1;
NSInteger endWeek = [NSDate br_getWeeksOfMonthInYear:year month:month];
if (year == self.minDate.br_year && month == self.minDate.br_month) {
startWeek = self.minDate.br_monthWeek;
}
if (year == self.maxDate.br_year && month == self.maxDate.br_month) {
endWeek = self.maxDate.br_monthWeek;
}
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = startWeek; i <= endWeek; i++) {
[tempArr addObject:[self getMDHMSNumber:i]];
}
if (self.isDescending) {
return [[tempArr reverseObjectEnumerator] allObjects];
}
return [tempArr copy];
}
#pragma mark - yearWeekArr
- (NSArray *)getYearWeekArr:(NSInteger)year {
NSInteger startWeek = 1;
NSInteger endWeek = [NSDate br_getWeeksOfYearInYear:year];
if (year == self.minDate.br_year) {
startWeek = self.minDate.br_yearWeek;
}
if (year == self.maxDate.br_year) {
endWeek = self.maxDate.br_yearWeek;
}
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = startWeek; i <= endWeek; i++) {
[tempArr addObject:[self getMDHMSNumber:i]];
}
if (self.isDescending) {
return [[tempArr reverseObjectEnumerator] allObjects];
}
return [tempArr copy];
}
#pragma mark - quarterArr
- (NSArray *)getQuarterArr:(NSInteger)year {
NSInteger startQuarter = 1;
NSInteger endQuarter = [NSDate br_getQuartersInYear:year];
if (year == self.minDate.br_year) {
startQuarter = self.minDate.br_quarter;
}
if (year == self.maxDate.br_year) {
endQuarter = self.maxDate.br_quarter;
}
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = startQuarter; i <= endQuarter; i++) {
[tempArr addObject:[self getMDHMSNumber:i]];
}
if (self.isDescending) {
return [[tempArr reverseObjectEnumerator] allObjects];
}
return [tempArr copy];
}
#pragma mark - pickerView
- (void)setupPickerView:(UIView *)pickerView toView:(UIView *)view {
if (view) {
// view view 使
[view setNeedsLayout];
[view layoutIfNeeded];
self.frame = view.bounds;
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
CGFloat pickerFooterViewHeight = self.pickerFooterView ? self.pickerFooterView.bounds.size.height : 0;
pickerView.frame = CGRectMake(0, pickerHeaderViewHeight, view.bounds.size.width, view.bounds.size.height - pickerHeaderViewHeight - pickerFooterViewHeight);
[self addSubview:pickerView];
} else {
// iOS16 pickerView frame
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
pickerView.frame = CGRectMake(0, self.pickerStyle.titleBarHeight + pickerHeaderViewHeight, self.keyView.bounds.size.width, self.pickerStyle.pickerHeight);
[self.alertView addSubview:pickerView];
}
}
#pragma mark -
- (NSArray *)setupPickerUnitLabel:(UIPickerView *)pickerView unitArr:(NSArray *)unitArr {
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
for (NSInteger i = 0; i < pickerView.numberOfComponents; i++) {
// label
CGFloat labelWidth = pickerView.bounds.size.width / pickerView.numberOfComponents;
//
NSString *tempText = @"00";
if (i == 0) {
switch (self.pickerMode) {
case BRDatePickerModeYMDHMS:
case BRDatePickerModeYMDHM:
case BRDatePickerModeYMDH:
case BRDatePickerModeYMD:
case BRDatePickerModeYM:
case BRDatePickerModeY:
{
tempText = @"0123";
}
break;
default:
break;
}
}
//
CGFloat labelTextWidth = [tempText boundingRectWithSize:CGSizeMake(MAXFLOAT, self.pickerStyle.rowHeight)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName: self.pickerStyle.pickerTextFont}
context:nil].size.width;
// label
UILabel *unitLabel = [[UILabel alloc]init];
unitLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
unitLabel.backgroundColor = [UIColor clearColor];
if (self.pickerMode != BRDatePickerModeYMDHMS) {
unitLabel.textAlignment = NSTextAlignmentCenter;
}
unitLabel.font = self.pickerStyle.dateUnitTextFont;
unitLabel.textColor = self.pickerStyle.dateUnitTextColor;
//
unitLabel.adjustsFontSizeToFitWidth = YES;
//
unitLabel.minimumScaleFactor = 0.5f;
unitLabel.text = (unitArr.count > 0 && i < unitArr.count) ? unitArr[i] : nil;
CGFloat originX = i * labelWidth + labelWidth / 2.0 + labelTextWidth / 2.0 + self.pickerStyle.dateUnitOffsetX;
CGFloat originY = (pickerView.frame.size.height - self.pickerStyle.rowHeight) / 2 + self.pickerStyle.dateUnitOffsetY;
unitLabel.frame = CGRectMake(originX, originY, MAX(self.pickerStyle.rowHeight, labelTextWidth), self.pickerStyle.rowHeight);
[tempArr addObject:unitLabel];
[pickerView addSubview:unitLabel];
}
return [tempArr copy];
}
- (NSString *)getYearNumber:(NSInteger)year {
NSString *yearString = [NSString stringWithFormat:@"%@", @(year)];
if (self.isNumberFullName) {
yearString = [NSString stringWithFormat:@"%04d", [yearString intValue]];
}
return yearString;
}
- (NSString *)getMDHMSNumber:(NSInteger)number {
NSString *string = [NSString stringWithFormat:@"%@", @(number)];
if (self.isNumberFullName) {
string = [NSString stringWithFormat:@"%02d", [string intValue]];
}
return string;
}
- (NSString *)getYearText:(NSArray *)yearArr row:(NSInteger)row {
NSInteger index = 0;
if (row >= 0) {
index = MIN(row, yearArr.count - 1);
}
NSString *yearString = [yearArr objectAtIndex:index];
if ((self.lastRowContent && [yearString isEqualToString:self.lastRowContent]) || (self.firstRowContent && [yearString isEqualToString:self.firstRowContent])) {
return yearString;
}
NSString *yearUnit = self.showUnitType == BRShowUnitTypeAll ? [self getYearUnit] : @"";
return [NSString stringWithFormat:@"%@%@", yearString, yearUnit];
}
- (NSString *)getMonthText:(NSArray *)monthArr row:(NSInteger)row {
NSInteger index = 0;
if (row >= 0) {
index = MIN(row, monthArr.count - 1);
}
NSString *monthString = [monthArr objectAtIndex:index];
// /
if ((self.firstRowContent && [monthString isEqualToString:self.firstRowContent]) || (self.lastRowContent && [monthString isEqualToString:self.lastRowContent])) {
return monthString;
}
//
if (self.monthNames && self.monthNames.count > 0) {
NSInteger index = [monthString integerValue] - 1;
monthString = (index >= 0 && index < self.monthNames.count) ? self.monthNames[index] : @"";
} else {
if (![self.pickerStyle.language hasPrefix:@"zh"] && (self.pickerMode == BRDatePickerModeYMD || self.pickerMode == BRDatePickerModeYM || self.pickerMode == BRDatePickerModeYMW)) {
// 使
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[NSLocale alloc]initWithLocaleIdentifier:self.pickerStyle.language];
// monthSymbols: @[@"January", @"February", @"March", @"April", @"May", @"June", @"July", @"August", @"September", @"October", @"November", @"December"];
// shortMonthSymbols: @[@"Jan", @"Feb", @"Mar", @"Apr", @"May", @"Jun", @"Jul", @"Aug", @"Sep", @"Oct", @"Nov", @"Dec"];
NSArray *monthNames = self.isShortMonthName ? dateFormatter.shortMonthSymbols : dateFormatter.monthSymbols;
NSInteger index = [monthString integerValue] - 1;
monthString = (index >= 0 && index < monthNames.count) ? monthNames[index] : @"";
} else {
//
NSString *monthUnit = self.showUnitType == BRShowUnitTypeAll ? [self getMonthUnit] : @"";
monthString = [NSString stringWithFormat:@"%@%@", monthString, monthUnit];
}
}
return monthString;
}
- (NSString *)getDayText:(NSArray *)dayArr row:(NSInteger)row mSelectDate:(NSDate *)mSelectDate {
NSInteger index = 0;
if (row >= 0) {
index = MIN(row, dayArr.count - 1);
}
NSString *dayString = [dayArr objectAtIndex:index];
if (self.isShowToday && mSelectDate.br_year == [NSDate date].br_year && mSelectDate.br_month == [NSDate date].br_month && [dayString integerValue] == [NSDate date].br_day) {
return [NSBundle br_localizedStringForKey:@"今天" language:self.pickerStyle.language];
}
NSString *dayUnit = self.showUnitType == BRShowUnitTypeAll ? [self getDayUnit] : @"";
dayString = [NSString stringWithFormat:@"%@%@", dayString, dayUnit];
if (self.isShowWeek) {
NSDate *date = [NSDate br_setYear:mSelectDate.br_year month:mSelectDate.br_month day:[dayString integerValue]];
NSString *weekdayString = [NSBundle br_localizedStringForKey:[date br_weekdayString] language:self.pickerStyle.language];
dayString = [NSString stringWithFormat:@"%@%@", dayString, weekdayString];
}
return dayString;
}
- (NSString *)getHourText:(NSArray *)hourArr row:(NSInteger)row {
NSInteger index = 0;
if (row >= 0) {
index = MIN(row, hourArr.count - 1);
}
NSString *hourString = [hourArr objectAtIndex:index];
if ((self.lastRowContent && [hourString isEqualToString:self.lastRowContent]) || (self.firstRowContent && [hourString isEqualToString:self.firstRowContent])) {
return hourString;
}
NSString *hourUnit = self.showUnitType == BRShowUnitTypeAll ? [self getHourUnit] : @"";
return [NSString stringWithFormat:@"%@%@", hourString, hourUnit];
}
- (NSString *)getMinuteText:(NSArray *)minuteArr row:(NSInteger)row {
NSInteger index = 0;
if (row >= 0) {
index = MIN(row, minuteArr.count - 1);
}
NSString *minuteString = [minuteArr objectAtIndex:index];
NSString *minuteUnit = self.showUnitType == BRShowUnitTypeAll ? [self getMinuteUnit] : @"";
return [NSString stringWithFormat:@"%@%@", minuteString, minuteUnit];
}
- (NSString *)getSecondText:(NSArray *)secondArr row:(NSInteger)row {
NSInteger index = 0;
if (row >= 0) {
index = MIN(row, secondArr.count - 1);
}
NSString *secondString = [secondArr objectAtIndex:index];
NSString *secondUnit = self.showUnitType == BRShowUnitTypeAll ? [self getSecondUnit] : @"";
return [NSString stringWithFormat:@"%@%@", secondString, secondUnit];
}
- (NSString *)getWeekText:(NSArray *)weekArr row:(NSInteger)row {
NSInteger index = 0;
if (row >= 0) {
index = MIN(row, weekArr.count - 1);
}
NSString *weekString = [weekArr objectAtIndex:index];
if ((self.lastRowContent && [weekString isEqualToString:self.lastRowContent]) || (self.firstRowContent && [weekString isEqualToString:self.firstRowContent])) {
return weekString;
}
NSString *weekUnit = self.showUnitType == BRShowUnitTypeAll ? [self getWeekUnit] : @"";
return [NSString stringWithFormat:@"%@%@", weekString, weekUnit];
}
- (NSString *)getQuarterText:(NSArray *)quarterArr row:(NSInteger)row {
NSInteger index = 0;
if (row >= 0) {
index = MIN(row, quarterArr.count - 1);
}
NSString *quarterString = [quarterArr objectAtIndex:index];
if ((self.lastRowContent && [quarterString isEqualToString:self.lastRowContent]) || (self.firstRowContent && [quarterString isEqualToString:self.firstRowContent])) {
return quarterString;
}
NSString *quarterUnit = self.showUnitType == BRShowUnitTypeAll ? [self getQuarterUnit] : @"";
return [NSString stringWithFormat:@"%@%@", quarterString, quarterUnit];
}
- (NSString *)getAMText {
return [NSBundle br_localizedStringForKey:@"上午" language:self.pickerStyle.language];
}
- (NSString *)getPMText {
return [NSBundle br_localizedStringForKey:@"下午" language:self.pickerStyle.language];
}
- (NSString *)getYearUnit {
if (self.customUnit) {
return self.customUnit[@"year"] ? : @"";
}
if (![self.pickerStyle.language hasPrefix:@"zh"]) {
return @"";
}
return [NSBundle br_localizedStringForKey:@"年" language:self.pickerStyle.language];
}
- (NSString *)getMonthUnit {
if (self.customUnit) {
return self.customUnit[@"month"] ? : @"";
}
if (![self.pickerStyle.language hasPrefix:@"zh"]) {
return @"";
}
return [NSBundle br_localizedStringForKey:@"月" language:self.pickerStyle.language];
}
- (NSString *)getDayUnit {
if (self.customUnit) {
return self.customUnit[@"day"] ? : @"";
}
if (![self.pickerStyle.language hasPrefix:@"zh"]) {
return @"";
}
return [NSBundle br_localizedStringForKey:@"日" language:self.pickerStyle.language];
}
- (NSString *)getHourUnit {
if (self.pickerMode == BRDatePickerModeYMDH && self.isShowAMAndPM) {
return @"";
}
if (self.customUnit) {
return self.customUnit[@"hour"] ? : @"";
}
if (![self.pickerStyle.language hasPrefix:@"zh"]) {
return @"";
}
return [NSBundle br_localizedStringForKey:@"时" language:self.pickerStyle.language];
}
- (NSString *)getMinuteUnit {
if (self.customUnit) {
return self.customUnit[@"minute"] ? : @"";
}
if (![self.pickerStyle.language hasPrefix:@"zh"]) {
return @"";
}
return [NSBundle br_localizedStringForKey:@"分" language:self.pickerStyle.language];
}
- (NSString *)getSecondUnit {
if (self.customUnit) {
return self.customUnit[@"second"] ? : @"";
}
if (![self.pickerStyle.language hasPrefix:@"zh"]) {
return @"";
}
return [NSBundle br_localizedStringForKey:@"秒" language:self.pickerStyle.language];
}
- (NSString *)getWeekUnit {
if (self.customUnit) {
return self.customUnit[@"week"] ? : @"";
}
if (![self.pickerStyle.language hasPrefix:@"zh"]) {
return @"";
}
return [NSBundle br_localizedStringForKey:@"周" language:self.pickerStyle.language];
}
- (NSString *)getQuarterUnit {
if (self.customUnit) {
return self.customUnit[@"quarter"] ? : @"";
}
if (![self.pickerStyle.language hasPrefix:@"zh"]) {
return @"";
}
return [NSBundle br_localizedStringForKey:@"季度" language:self.pickerStyle.language];
}
- (NSInteger)getIndexWithArray:(NSArray *)array object:(NSString *)obj {
if (!array || array.count == 0 || !obj) {
return 0;
}
if ([array containsObject:obj]) {
return [array indexOfObject:obj];
}
return 0;
}
@end

View File

@@ -0,0 +1,274 @@
//
// BRDatePickerView.h
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import "BRBaseView.h"
#import "NSDate+BRPickerView.h"
NS_ASSUME_NONNULL_BEGIN
/// 日期选择器格式
typedef NS_ENUM(NSInteger, BRDatePickerMode) {
// ----- 以下4种是系统样式兼容国际化日期格式 -----
/** 【yyyy-MM-dd】UIDatePickerModeDate美式日期MM-dd-yyyy英式日期dd-MM-yyyy*/
BRDatePickerModeDate,
/** 【yyyy-MM-dd HH:mm】 UIDatePickerModeDateAndTime */
BRDatePickerModeDateAndTime,
/** 【HH:mm】UIDatePickerModeTime */
BRDatePickerModeTime,
/** 【HH:mm】UIDatePickerModeCountDownTimer */
BRDatePickerModeCountDownTimer,
// ----- 以下14种是自定义样式 -----
/** 【yyyy-MM-dd HH:mm:ss】年月日时分秒 */
BRDatePickerModeYMDHMS,
/** 【yyyy-MM-dd HH:mm】年月日时分 */
BRDatePickerModeYMDHM,
/** 【yyyy-MM-dd HH】年月日时 */
BRDatePickerModeYMDH,
/** 【MM-dd HH:mm】月日时分 */
BRDatePickerModeMDHM,
/** 【yyyy-MM-dd】年月日兼容国际化日期dd-MM-yyyy*/
BRDatePickerModeYMD,
/** 【yyyy-MM】年月兼容国际化日期MM-yyyy*/
BRDatePickerModeYM,
/** 【yyyy】年 */
BRDatePickerModeY,
/** 【MM-dd】月日 */
BRDatePickerModeMD,
/** 【HH:mm:ss】时分秒 */
BRDatePickerModeHMS,
/** 【HH:mm】时分 */
BRDatePickerModeHM,
/** 【mm:ss】分秒 */
BRDatePickerModeMS,
/** 【yyyy-qq】年季度 */
BRDatePickerModeYQ,
/** 【yyyy-MM-ww】年月周 */
BRDatePickerModeYMW,
/** 【yyyy-ww】年周 */
BRDatePickerModeYW
};
/// 日期单位显示的位置
typedef NS_ENUM(NSInteger, BRShowUnitType) {
/** 日期单位显示全部行(默认)*/
BRShowUnitTypeAll,
/** 日期单位仅显示中间行 */
BRShowUnitTypeOnlyCenter,
/** 日期单位不显示(隐藏日期单位)*/
BRShowUnitTypeNone
};
typedef void (^BRDateResultBlock)(NSDate * _Nullable selectDate, NSString * _Nullable selectValue);
typedef void (^BRDateResultRangeBlock)(NSDate * _Nullable selectStartDate, NSDate * _Nullable selectEndDate, NSString * _Nullable selectValue);
@interface BRDatePickerView : BRBaseView
/**
//////////////////////////////////////////////////////////////////////////
///
/// 【用法一】
/// 特点:灵活,扩展性强(推荐使用!)
///
////////////////////////////////////////////////////////////////////////*/
/** 日期选择器显示类型 */
@property (nonatomic, assign) BRDatePickerMode pickerMode;
/** 设置选中的日期(推荐使用 selectDate */
@property (nullable, nonatomic, strong) NSDate *selectDate;
@property (nullable, nonatomic, copy) NSString *selectValue;
/** 最小日期(可使用 NSDate+BRPickerView 分类中对应的方法进行创建)*/
@property (nullable, nonatomic, strong) NSDate *minDate;
/** 最大日期(可使用 NSDate+BRPickerView 分类中对应的方法进行创建)*/
@property (nullable, nonatomic, strong) NSDate *maxDate;
/** 选择结果的回调 */
@property (nullable, nonatomic, copy) BRDateResultBlock resultBlock;
/** 选择结果范围的回调for `BRDatePickerModeYQ`、`BRDatePickerModeYMW`、`BRDatePickerModeYW`, ignored otherwise. */
@property (nullable, nonatomic, copy) BRDateResultRangeBlock resultRangeBlock;
/** 滚动选择时触发的回调 */
@property (nullable, nonatomic, copy) BRDateResultBlock changeBlock;
/** 滚动选择范围时触发的回调for `BRDatePickerModeYQ`、`BRDatePickerModeYMW`、`BRDatePickerModeYW`, ignored otherwise. */
@property (nullable, nonatomic, copy) BRDateResultRangeBlock changeRangeBlock;
/** 日期单位显示类型 */
@property (nonatomic, assign) BRShowUnitType showUnitType;
/** 是否显示【星期】,默认为 NO */
@property (nonatomic, assign, getter=isShowWeek) BOOL showWeek;
/** 是否显示【今天】,默认为 NO */
@property (nonatomic, assign, getter=isShowToday) BOOL showToday;
/** 是否添加【至今】,默认为 NO */
@property (nonatomic, assign, getter=isAddToNow) BOOL addToNow;
/** 首行添加【自定义字符串】,配合 selectValue 可设置默认选中 */
@property (nullable, nonatomic, copy) NSString *firstRowContent;
/** 末行添加【自定义字符串】,配合 selectValue 可设置默认选中 */
@property (nullable, nonatomic, copy) NSString *lastRowContent;
/** 最后一行,添加【自定义字符串】 */
@property (nullable, nonatomic, copy) NSString *addCustomString DEPRECATED_MSG_ATTRIBUTE("Use 'lastRowContent' instead");
/** 滚轮上日期数据排序是否降序,默认为 NO升序*/
@property (nonatomic, assign, getter=isDescending) BOOL descending;
/** 选择器上数字是否带有前导零,默认为 NO无前导零:2020-1-1有前导零:2020-01-01*/
@property (nonatomic, assign, getter=isNumberFullName) BOOL numberFullName;
/** 设置分的时间间隔默认为1范围1 ~ 30*/
@property (nonatomic, assign) NSInteger minuteInterval;
/** 设置秒的时间间隔默认为1范围1 ~ 30*/
@property (nonatomic, assign) NSInteger secondInterval;
/** 设置倒计时的时长默认为0范围0 ~ 24*60*60-1单位为秒 for `BRDatePickerModeCountDownTimer`, ignored otherwise. */
@property (nonatomic, assign) NSTimeInterval countDownDuration;
/**
* 自定义月份数据源
* 如:@[@"1月", @"2月",..., @"12月"]、 @[@"一月", @"二月",..., @"十二月"]、 @[@"Jan", @"Feb",..., @"Dec"] 等
*/
@property (nonatomic, copy) NSArray <NSString *> *monthNames;
/**
* 设置国际化日期(非中文环境下)月份是否显示简称,默认为 NO。for `BRDatePickerModeYMD` and `BRDatePickerModeYM`, ignored otherwise.
* 如January 的简称为Jan
*/
@property (nonatomic, assign, getter=isShortMonthName) BOOL shortMonthName;
/**
* 自定义日期单位
* 字典格式:@{@"year": @"年", @"month": @"月", @"day": @"日", @"hour": @"时", @"minute": @"分", @"second": @"秒"}
*/
@property (nonatomic, copy) NSDictionary *customUnit;
/** 显示上午和下午,默认为 NO. for `BRDatePickerModeYMDH`, ignored otherwise. */
@property (nonatomic, assign, getter=isShowAMAndPM) BOOL showAMAndPM;
/** 设置时区,默认为当前时区 */
@property (nullable, nonatomic, copy) NSTimeZone *timeZone;
/** default is [NSCalendar currentCalendar]. setting nil returns to default. for `UIDatePicker` */
@property (nonatomic, copy) NSCalendar *calendar;
/** 指定不允许选择的日期 */
@property (nullable, nonatomic, copy) NSArray <NSDate *> *nonSelectableDates;
/** 不允许选择日期的回调 */
@property (nullable, nonatomic, copy) BRDateResultBlock nonSelectableBlock;
/// 初始化日期选择器
/// @param pickerMode 日期选择器显示类型
- (instancetype)initWithPickerMode:(BRDatePickerMode)pickerMode;
/// 弹出选择器视图
- (void)show;
/// 关闭选择器视图
- (void)dismiss;
//================================================= 华丽的分割线 =================================================
/**
//////////////////////////////////////////////////////////////////////////
///
/// 【用法二】:快捷使用,直接选择下面其中的一个方法进行使用
/// 特点:快捷,方便
///
////////////////////////////////////////////////////////////////////////*/
/**
* 1.显示日期选择器
*
* @param mode 日期显示类型
* @param title 选择器标题
* @param selectValue 默认选中的日期(默认选中当前日期)
* @param resultBlock 选择结果的回调
*
*/
+ (void)showDatePickerWithMode:(BRDatePickerMode)mode
title:(nullable NSString *)title
selectValue:(nullable NSString *)selectValue
resultBlock:(nullable BRDateResultBlock)resultBlock;
/**
* 2.显示日期选择器
*
* @param mode 日期显示类型
* @param title 选择器标题
* @param selectValue 默认选中的日期(默认选中当前日期)
* @param isAutoSelect 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO
* @param resultBlock 选择结果的回调
*
*/
+ (void)showDatePickerWithMode:(BRDatePickerMode)mode
title:(nullable NSString *)title
selectValue:(nullable NSString *)selectValue
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRDateResultBlock)resultBlock;
/**
* 3.显示日期选择器
*
* @param mode 日期显示类型
* @param title 选择器标题
* @param selectValue 默认选中的日期(默认选中当前日期)
* @param minDate 最小日期(可使用 NSDate+BRPickerView 分类中对应的方法进行创建)
* @param maxDate 最大日期(可使用 NSDate+BRPickerView 分类中对应的方法进行创建)
* @param isAutoSelect 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO
* @param resultBlock 选择结果的回调
*
*/
+ (void)showDatePickerWithMode:(BRDatePickerMode)mode
title:(nullable NSString *)title
selectValue:(nullable NSString *)selectValue
minDate:(nullable NSDate *)minDate
maxDate:(nullable NSDate *)maxDate
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRDateResultBlock)resultBlock;
/**
* 3.显示日期选择器
*
* @param mode 日期显示类型
* @param title 选择器标题
* @param selectValue 默认选中的日期(默认选中当前日期)
* @param minDate 最小日期(可使用 NSDate+BRPickerView 分类中对应的方法进行创建)
* @param maxDate 最大日期(可使用 NSDate+BRPickerView 分类中对应的方法进行创建)
* @param isAutoSelect 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO
* @param resultBlock 选择结果的回调
* @param resultRangeBlock 范围选择结果的回调
*
*/
+ (void)showDatePickerWithMode:(BRDatePickerMode)mode
title:(nullable NSString *)title
selectValue:(nullable NSString *)selectValue
minDate:(nullable NSDate *)minDate
maxDate:(nullable NSDate *)maxDate
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRDateResultBlock)resultBlock
resultRangeBlock:(nullable BRDateResultRangeBlock)resultRangeBlock;
@end
NS_ASSUME_NONNULL_END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,126 @@
//
// NSDate+BRPickerView.h
// BRPickerViewDemo
//
// Created by renbo on 2018/3/15.
// Copyright © 2018 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSDate (BRPickerView)
/// 获取指定date的详细信息
@property (readonly) NSInteger br_year; // 年
@property (readonly) NSInteger br_month; // 月
@property (readonly) NSInteger br_day; // 日
@property (readonly) NSInteger br_hour; // 时
@property (readonly) NSInteger br_minute; // 分
@property (readonly) NSInteger br_second; // 秒
@property (readonly) NSInteger br_weekday; // 星期
@property (readonly) NSInteger br_monthWeek; // 月周
@property (readonly) NSInteger br_yearWeek; // 年周
@property (readonly) NSInteger br_quarter; // 季度
/** 获取中文星期字符串 */
@property (nullable, nonatomic, readonly, copy) NSString *br_weekdayString;
/** 获取日历单例对象 */
+ (NSCalendar *)br_calendar;
/// ---------------- 创建 date ----------------
/** 通过 NSDateComponents对象 来创建 NSDate对象可以设置时区 */
+ (nullable NSDate *)br_setDateFromComponents:(NSDateComponents *)components timeZone:(NSTimeZone *)timeZone;
/** yyyy */
+ (nullable NSDate *)br_setYear:(NSInteger)year;
/** yyyy-MM */
+ (nullable NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month;
/** yyyy-MM-dd */
+ (nullable NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;
/** yyyy-MM-dd HH */
+ (nullable NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour;
/** yyyy-MM-dd HH:mm */
+ (nullable NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute;
/** yyyy-MM-dd HH:mm:ss */
+ (nullable NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second;
/** MM-dd HH:mm */
+ (nullable NSDate *)br_setMonth:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute;
/** MM-dd */
+ (nullable NSDate *)br_setMonth:(NSInteger)month day:(NSInteger)day;
/** HH:mm:ss */
+ (nullable NSDate *)br_setHour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second;
/** HH:mm */
+ (nullable NSDate *)br_setHour:(NSInteger)hour minute:(NSInteger)minute;
/** mm:ss */
+ (nullable NSDate *)br_setMinute:(NSInteger)minute second:(NSInteger)second;
/** yyyy-MM-ww */
+ (nullable NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month weekOfMonth:(NSInteger)weekOfMont;
/** yyyy-ww */
+ (nullable NSDate *)br_setYear:(NSInteger)year weekOfYear:(NSInteger)weekOfYear;
/** yyyy-qq */
+ (nullable NSDate *)br_setYear:(NSInteger)year quarter:(NSInteger)quarter;
/** 获取某个月的天数(通过年月求每月天数)*/
+ (NSUInteger)br_getDaysInYear:(NSInteger)year month:(NSInteger)month;
/** 获取某个月的周数(通过年月求该月周数)*/
+ (NSUInteger)br_getWeeksOfMonthInYear:(NSInteger)year month:(NSInteger)month;
/** 获取某一年的周数(通过年求该年周数)*/
+ (NSUInteger)br_getWeeksOfYearInYear:(NSInteger)year;
/** 获取某一年的季度数(通过年求该年季度数)*/
+ (NSUInteger)br_getQuartersInYear:(NSInteger)year;
/** 获取 日期加上/减去某天数后的新日期 */
- (nullable NSDate *)br_getNewDateToDays:(NSTimeInterval)days;
/** 获取 日期加上/减去某个月数后的新日期 */
- (nullable NSDate *)br_getNewDateToMonths:(NSTimeInterval)months;
/** NSDate 转 NSString */
+ (nullable NSString *)br_stringFromDate:(NSDate *)date dateFormat:(NSString *)dateFormat;
/** NSDate 转 NSString */
+ (nullable NSString *)br_stringFromDate:(NSDate *)date
dateFormat:(NSString *)dateFormat
timeZone:(nullable NSTimeZone *)timeZone
language:(nullable NSString *)language;
/** NSString 转 NSDate */
+ (nullable NSDate *)br_dateFromString:(NSString *)dateString dateFormat:(NSString *)dateFormat;
/** NSString 转 NSDate */
+ (nullable NSDate *)br_dateFromString:(NSString *)dateString
dateFormat:(NSString *)dateFormat
timeZone:(nullable NSTimeZone *)timeZone
language:(nullable NSString *)language;
/** NSDate 转 NSString已弃用 */
+ (nullable NSString *)br_getDateString:(NSDate *)date format:(NSString *)format DEPRECATED_MSG_ATTRIBUTE("Use 'br_stringFromDate:dateFormat:' instead");
/** NSString 转 NSDate已弃用 */
+ (nullable NSDate *)br_getDate:(NSString *)dateString format:(NSString *)format DEPRECATED_MSG_ATTRIBUTE("Use 'br_dateFromString:dateFormat:' instead");
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,400 @@
//
// NSDate+BRPickerView.m
// BRPickerViewDemo
//
// Created by renbo on 2018/3/15.
// Copyright © 2018 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "NSDate+BRPickerView.h"
#import "BRPickerViewMacro.h"
BRSYNTH_DUMMY_CLASS(NSDate_BRPickerView)
static const NSCalendarUnit unitFlags = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekOfYear | NSCalendarUnitWeekOfMonth | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal | NSCalendarUnitQuarter);
@implementation NSDate (BRPickerView)
#pragma mark -
+ (NSCalendar *)br_calendar {
static NSCalendar *sharedCalendar = nil;
if (!sharedCalendar) {
// /
sharedCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
// NSCalendar
//sharedCalendar.timeZone = [NSTimeZone timeZoneWithName:@"America/Chicago"];
}
return sharedCalendar;
}
#pragma mark - NSDate NSDateComponents
+ (NSDateComponents *)br_componentsFromDate:(NSDate *)date {
// NSCalendar
NSCalendar *calendar = [self br_calendar];
// NSDateComponents
return [calendar components:unitFlags fromDate:date];
}
#pragma mark - NSDateComponents NSDate
+ (NSDate *)br_dateFromComponents:(NSDateComponents *)components {
// NSCalendar
NSCalendar *calendar = [self br_calendar];
return [calendar dateFromComponents:components];
}
#pragma mark -
- (NSInteger)br_year {
return [NSDate br_componentsFromDate:self].year;
}
#pragma mark -
- (NSInteger)br_month {
return [NSDate br_componentsFromDate:self].month;
}
#pragma mark -
- (NSInteger)br_day {
return [NSDate br_componentsFromDate:self].day;
}
#pragma mark -
- (NSInteger)br_hour {
return [NSDate br_componentsFromDate:self].hour;
}
#pragma mark -
- (NSInteger)br_minute {
return [NSDate br_componentsFromDate:self].minute;
}
#pragma mark -
- (NSInteger)br_second {
return [NSDate br_componentsFromDate:self].second;
}
#pragma mark -
- (NSInteger)br_weekday {
return [NSDate br_componentsFromDate:self].weekday;
}
#pragma mark -
- (NSInteger)br_monthWeek {
return [NSDate br_componentsFromDate:self].weekOfMonth;
}
#pragma mark -
- (NSInteger)br_yearWeek {
return [NSDate br_componentsFromDate:self].weekOfYear;
}
#pragma mark -
- (NSInteger)br_quarter {
// [NSDate br_componentsFromDate:self].quarter; // 0?
NSInteger quarter = 1;
NSInteger month = self.br_month;
if (month > 3) quarter = 2;
if (month > 6) quarter = 3;
if (month > 9) quarter = 4;
return quarter;
}
#pragma mark -
- (NSString *)br_weekdayString {
switch (self.br_weekday - 1) {
case 0:
{
return @"周日";
}
break;
case 1:
{
return @"周一";
}
break;
case 2:
{
return @"周二";
}
break;
case 3:
{
return @"周三";
}
break;
case 4:
{
return @"周四";
}
break;
case 5:
{
return @"周五";
}
break;
case 6:
{
return @"周六";
}
break;
default:
break;
}
return @"";
}
/// ---------------- date ----------------
#pragma mark - NSDateComponents NSDate
+ (nullable NSDate *)br_setDateFromComponents:(NSDateComponents *)components timeZone:(NSTimeZone *)timeZone {
// /
NSCalendar *calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
if (timeZone) {
// NSCalendar
calendar.timeZone = timeZone;
}
return [calendar dateFromComponents:components];
}
#pragma mark - date NSCalendar
+ (NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second {
return [self br_setYear:year month:month day:day hour:hour minute:minute second:second weekOfMonth:0 weekOfYear:0 quarter:0];
}
+ (NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day
hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second
weekOfMonth:(NSInteger)weekOfMonth weekOfYear:(NSInteger)weekOfYear quarter:(NSInteger)quarter {
NSDateComponents *components = [self br_componentsFromDate:[NSDate date]];
if (year > 0) {
//
components = [[NSDateComponents alloc]init];
components.year = year;
}
if (month > 0) {
components.month = month;
}
if (day > 0) {
components.day = day;
}
if (hour >= 0) {
components.hour = hour;
}
if (minute >= 0) {
components.minute = minute;
}
if (second >= 0) {
components.second = second;
}
if (weekOfMonth > 0) {
components.weekOfMonth = weekOfMonth;
}
if (weekOfYear > 0) {
components.weekOfYear = weekOfYear;
}
if (quarter > 0) {
components.quarter = quarter;
}
return [self br_dateFromComponents:components];
}
+ (NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute {
return [self br_setYear:year month:month day:day hour:hour minute:minute second:0];
}
+ (NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour {
return [self br_setYear:year month:month day:day hour:hour minute:0 second:0];
}
+ (NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day {
return [self br_setYear:year month:month day:day hour:0 minute:0 second:0];
}
+ (NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month {
return [self br_setYear:year month:month day:0 hour:0 minute:0 second:0];
}
+ (NSDate *)br_setYear:(NSInteger)year {
return [self br_setYear:year month:0 day:0 hour:0 minute:0 second:0];
}
+ (NSDate *)br_setMonth:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute {
return [self br_setYear:0 month:month day:day hour:hour minute:minute second:0];
}
+ (NSDate *)br_setMonth:(NSInteger)month day:(NSInteger)day {
return [self br_setYear:0 month:month day:day hour:0 minute:0 second:0];
}
+ (NSDate *)br_setHour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second {
return [self br_setYear:0 month:0 day:0 hour:hour minute:minute second:second];
}
+ (NSDate *)br_setHour:(NSInteger)hour minute:(NSInteger)minute {
return [self br_setYear:0 month:0 day:0 hour:hour minute:minute second:0];
}
+ (NSDate *)br_setMinute:(NSInteger)minute second:(NSInteger)second {
return [self br_setYear:0 month:0 day:0 hour:0 minute:minute second:second];
}
+ (NSDate *)br_setYear:(NSInteger)year month:(NSInteger)month weekOfMonth:(NSInteger)weekOfMonth {
return [self br_setYear:year month:month day:0 hour:0 minute:0 second:0 weekOfMonth:weekOfMonth weekOfYear:0 quarter:0];
}
+ (NSDate *)br_setYear:(NSInteger)year weekOfYear:(NSInteger)weekOfYear {
return [self br_setYear:year month:0 day:0 hour:0 minute:0 second:0 weekOfMonth:0 weekOfYear:weekOfYear quarter:0];
}
+ (NSDate *)br_setYear:(NSInteger)year quarter:(NSInteger)quarter {
return [self br_setYear:year month:0 day:0 hour:0 minute:0 second:0 weekOfMonth:0 weekOfYear:0 quarter:quarter];
}
#pragma mark -
+ (NSUInteger)br_getDaysInYear:(NSInteger)year month:(NSInteger)month {
BOOL isLeapYear = year % 4 == 0 ? (year % 100 == 0 ? (year % 400 == 0 ? YES : NO) : YES) : NO;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
{
return 31;
}
case 4:
case 6:
case 9:
case 11:
{
return 30;
}
case 2:
{
if (isLeapYear) {
return 29;
} else {
return 28;
}
}
default:
break;
}
return 0;
}
#pragma mark -
+ (NSUInteger)br_getWeeksOfMonthInYear:(NSInteger)year month:(NSInteger)month {
NSUInteger lastDayOfMonth = [self br_getDaysInYear:year month:month];
NSDate *endDate = [self br_setYear:year month:month day:lastDayOfMonth];
return endDate.br_monthWeek;
}
#pragma mark -
+ (NSUInteger)br_getWeeksOfYearInYear:(NSInteger)year {
NSDate *endDate = [self br_setYear:year month:12 day:31];
NSInteger weeks = endDate.br_yearWeek;
if (weeks == 1) weeks = 52;
return weeks;
}
#pragma mark -
+ (NSUInteger)br_getQuartersInYear:(NSInteger)year {
NSDate *endDate = [self br_setYear:year month:12 day:31];
return endDate.br_quarter;
}
#pragma mark - /
- (NSDate *)br_getNewDateToDays:(NSTimeInterval)days {
// days
return [self dateByAddingTimeInterval:60 * 60 * 24 * days];
}
#pragma mark - /
- (nullable NSDate *)br_getNewDateToMonths:(NSTimeInterval)months {
// months
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setMonth:months];
NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
return [calender dateByAddingComponents:components toDate:self options:0];
}
#pragma mark - NSDate NSString
+ (NSString *)br_stringFromDate:(NSDate *)date dateFormat:(NSString *)dateFormat {
return [self br_stringFromDate:date dateFormat:dateFormat timeZone:nil language:nil];
}
#pragma mark - NSDate NSString
+ (NSString *)br_stringFromDate:(NSDate *)date
dateFormat:(NSString *)dateFormat
timeZone:(NSTimeZone *)timeZone
language:(NSString *)language {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//
dateFormatter.dateFormat = dateFormat;
// NSDateFormatter
if (timeZone) {
dateFormatter.timeZone = timeZone;
}
if (!language) {
language = [NSLocale preferredLanguages].firstObject;
}
dateFormatter.locale = [[NSLocale alloc]initWithLocaleIdentifier:language];
NSString *dateString = [dateFormatter stringFromDate:date];
return dateString;
}
#pragma mark - NSString NSDate
+ (NSDate *)br_dateFromString:(NSString *)dateString dateFormat:(NSString *)dateFormat {
return [self br_dateFromString:dateString dateFormat:dateFormat timeZone:nil language:nil];
}
#pragma mark - NSString NSDate
+ (NSDate *)br_dateFromString:(NSString *)dateString
dateFormat:(NSString *)dateFormat
timeZone:(NSTimeZone *)timeZone
language:(NSString *)language {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//
dateFormatter.dateFormat = dateFormat;
//
if (!timeZone) {
timeZone = [self currentTimeZone];
}
if (!language) {
language = [NSLocale preferredLanguages].firstObject;
}
dateFormatter.timeZone = timeZone;
dateFormatter.locale = [[NSLocale alloc]initWithLocaleIdentifier:language];
//
dateFormatter.lenient = YES;
return [dateFormatter dateFromString:dateString];
}
#pragma mark - (使)
+ (NSTimeZone *)currentTimeZone {
//
NSTimeZone *localTimeZone = [NSTimeZone localTimeZone];
// GMT()
NSInteger interval = [localTimeZone secondsFromGMTForDate:[NSDate date]];
// (使)NSTimeZone
// NSString NSDate NSDateFormatter null
return [NSTimeZone timeZoneForSecondsFromGMT:interval];
}
#pragma mark - NSDate NSString
+ (NSString *)br_getDateString:(NSDate *)date format:(NSString *)format {
return [self br_stringFromDate:date dateFormat:format];
}
#pragma mark - NSString NSDate
+ (NSDate *)br_getDate:(NSString *)dateString format:(NSString *)format {
return [self br_dateFromString:dateString dateFormat:format];
}
@end

View File

@@ -0,0 +1,37 @@
//
// BRResultModel.h
// BRPickerViewDemo
//
// Created by renbo on 2019/10/2.
// Copyright © 2019 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface BRResultModel : NSObject
/** key */
@property (nullable, nonatomic, copy) NSString *key;
/** value */
@property (nullable, nonatomic, copy) NSString *value;
/** 父级key提示联动时第一级数据parentKey设置为@"-1" */
@property (nullable, nonatomic, copy) NSString *parentKey;
/** 父级value */
@property (nullable, nonatomic, copy) NSString *parentValue;
/** 级别 */
@property (nullable, nonatomic, copy) NSString *level;
/** 子级list */
@property (nullable, nonatomic, copy) NSArray<BRResultModel *> *children;
/** 记录选择的索引位置 */
@property (nonatomic, assign) NSInteger index;
/// 其它扩展字段
@property (nullable, nonatomic, strong) id extras;
@property (nullable, nonatomic, copy) NSString *remark;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,41 @@
//
// BRResultModel.m
// BRPickerViewDemo
//
// Created by renbo on 2019/10/2.
// Copyright © 2019 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "BRResultModel.h"
@implementation BRResultModel
///
/// @param object
- (BOOL)isEqual:(id)object {
// 1.
if (self == object) {
return YES;
}
if (![object isKindOfClass:[BRResultModel class]]) {
return NO;
}
BRResultModel *model = (BRResultModel *)object;
if (!model) {
return NO;
}
// 2.
BOOL isSameKey = (!self.key && !model.key) || [self.key isEqualToString:model.key];
BOOL isSameValue = (!self.value && !model.value) || [self.value isEqualToString:model.value];
return isSameKey && isSameValue;
}
- (NSUInteger)hash {
return [self.key hash] ^ [self.value hash];
}
@end

View File

@@ -0,0 +1,191 @@
//
// BRStringPickerView.h
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// 最新代码下载地址https://github.com/91renb/BRPickerView
#import "BRBaseView.h"
#import "BRResultModel.h"
NS_ASSUME_NONNULL_BEGIN
/// 字符串选择器类型
typedef NS_ENUM(NSInteger, BRStringPickerMode) {
/** 单列选择器 */
BRStringPickerComponentSingle,
/** 多列选择器 */
BRStringPickerComponentMulti,
/** 多级联动选择器 */
BRStringPickerComponentLinkage
};
typedef void(^BRStringResultModelBlock)(BRResultModel * _Nullable resultModel);
typedef void(^BRStringResultModelArrayBlock)(NSArray <BRResultModel *> * _Nullable resultModelArr);
@interface BRStringPickerView : BRBaseView
/**
//////////////////////////////////////////////////////////////////////////
///
/// 【用法一】
/// 特点:灵活,扩展性强(推荐使用!)
///
////////////////////////////////////////////////////////////////////////*/
/** 字符串选择器显示类型 */
@property (nonatomic, assign) BRStringPickerMode pickerMode;
/**
* 1.设置数据源
* 单列:@[@"男", @"女", @"其他"],或直接传一维模型数组(NSArray <BRResultModel *>*)
* 多列:@[@[@"语文", @"数学", @"英语"], @[@"优秀", @"良好"]],或直接传多维模型数组
* 联动:直接传一维模型数组(NSArray <BRResultModel *>*)要注意数据源联动格式可参考Demo
*/
@property (nullable, nonatomic, copy) NSArray *dataSourceArr;
/**
* 2.设置数据源
* 直接传plist文件名NSString类型@"test.plist"),要带后缀名
* 场景可以将数据源数据数组类型放到plist文件中直接传plist文件名更加简单
*/
@property (nullable, nonatomic, copy) NSString *plistName;
/**
* 设置默认选中的位置【单列】
* 推荐使用 selectIndex更加严谨可以避免使用 selectValue 时,有名称相同的情况
*/
@property (nonatomic, assign) NSInteger selectIndex;
@property (nullable, nonatomic, copy) NSString *selectValue;
/**
* 设置默认选中的位置【多列】
* 推荐使用 selectIndexs更加严谨可以避免使用 selectValues 时,有名称相同的情况
*/
@property (nullable, nonatomic, copy) NSArray <NSNumber *> *selectIndexs;
@property (nullable, nonatomic, copy) NSArray <NSString *> *selectValues;
/** 选择结果的回调【单列】 */
@property (nullable, nonatomic, copy) BRStringResultModelBlock resultModelBlock;
/** 选择结果的回调【多列】 */
@property (nullable, nonatomic, copy) BRStringResultModelArrayBlock resultModelArrayBlock;
/** 滚动选择时触发的回调【单列】 */
@property (nullable, nonatomic, copy) BRStringResultModelBlock changeModelBlock;
/** 滚动选择时触发的回调【多列】 */
@property (nullable, nonatomic, copy) BRStringResultModelArrayBlock changeModelArrayBlock;
/**
* 最大层级数(列数) for `BRStringPickerComponentLinkage`, ignored otherwise.
* 使用场景:默认可选,当数据源中有 key 等于 parentKey 情况时,必须要设置
*/
@property (nonatomic, assign) NSInteger numberOfComponents;
/// 初始化字符串选择器
/// @param pickerMode 字符串选择器显示类型
- (instancetype)initWithPickerMode:(BRStringPickerMode)pickerMode;
/// 弹出选择器视图
- (void)show;
/// 关闭选择器视图
- (void)dismiss;
//================================================= 华丽的分割线 =================================================
/**
//////////////////////////////////////////////////////////////////////////
///
/// 【用法二】:快捷使用,直接选择下面其中的一个方法进行使用
/// 特点:快捷,方便
///
////////////////////////////////////////////////////////////////////////*/
/**
* 1.显示【单列】选择器
*
* @param title 选择器标题
* @param dataSourceArr 数据源,格式:@[@"男", @"女", @"其他"],或直接传一维模型数组(NSArray <BRResultModel *>*)
* @param selectIndex 默认选中的位置
* @param resultBlock 选择后的回调
*
*/
+ (void)showPickerWithTitle:(nullable NSString *)title
dataSourceArr:(nullable NSArray *)dataSourceArr
selectIndex:(NSInteger)selectIndex
resultBlock:(nullable BRStringResultModelBlock)resultBlock;
/**
* 2.显示【单列】选择器
*
* @param title 选择器标题
* @param dataSourceArr 数据源(如:@[@"男", @"女", @"其他"],或直接传模型数组)
* @param selectIndex 默认选中的位置
* @param isAutoSelect 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO
* @param resultBlock 选择后的回调
*
*/
+ (void)showPickerWithTitle:(nullable NSString *)title
dataSourceArr:(nullable NSArray *)dataSourceArr
selectIndex:(NSInteger)selectIndex
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRStringResultModelBlock)resultBlock;
/**
* 3.显示【多列】选择器
*
* @param title 选择器标题
* @param dataSourceArr 数据源,格式:@[@[@"语文", @"数学", @"英语"], @[@"优秀", @"良好"]],或直接传多维模型数组
* @param selectIndexs 默认选中的位置(传索引数组,如:@[@2, @1]
* @param resultBlock 选择后的回调
*
*/
+ (void)showMultiPickerWithTitle:(nullable NSString *)title
dataSourceArr:(nullable NSArray *)dataSourceArr
selectIndexs:(nullable NSArray <NSNumber *> *)selectIndexs
resultBlock:(nullable BRStringResultModelArrayBlock)resultBlock;
/**
* 4.显示【多列】选择器
*
* @param title 选择器标题
* @param dataSourceArr 数据源,格式:@[@[@"语文", @"数学", @"英语"], @[@"优秀", @"良好"]],或直接传多维模型数组
* @param selectIndexs 默认选中的位置(传索引数组,如:@[@2, @1]
* @param isAutoSelect 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO
* @param resultBlock 选择后的回调
*
*/
+ (void)showMultiPickerWithTitle:(nullable NSString *)title
dataSourceArr:(nullable NSArray *)dataSourceArr
selectIndexs:(nullable NSArray <NSNumber *> *)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRStringResultModelArrayBlock)resultBlock;
/**
* 5.显示【联动】选择器
*
* @param title 选择器标题
* @param dataSourceArr 数据源,格式:直接传一维模型数组(NSArray <BRResultModel *>*)
* @param selectIndexs 默认选中的位置(传索引数组,如:@[@2, @1]
* @param isAutoSelect 是否自动选择,即滚动选择器后就执行结果回调,默认为 NO
* @param resultBlock 选择后的回调
*
*/
+ (void)showLinkagePickerWithTitle:(nullable NSString *)title
dataSourceArr:(nullable NSArray *)dataSourceArr
selectIndexs:(nullable NSArray <NSNumber *> *)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRStringResultModelArrayBlock)resultBlock;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,571 @@
//
// BRStringPickerView.m
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "BRStringPickerView.h"
@interface BRStringPickerView ()<UIPickerViewDelegate, UIPickerViewDataSource>
{
BOOL _dataSourceException; //
}
/** */
@property (nonatomic, strong) UIPickerView *pickerView;
/** */
@property (nonatomic, copy) NSString *mSelectValue;
/** */
@property (nonatomic, copy) NSArray <NSString *>* mSelectValues;
/** */
@property (nullable, nonatomic, copy) NSArray *mDataSourceArr;
@end
@implementation BRStringPickerView
#pragma mark - 1.
+ (void)showPickerWithTitle:(NSString *)title
dataSourceArr:(NSArray *)dataSourceArr
selectIndex:(NSInteger)selectIndex
resultBlock:(BRStringResultModelBlock)resultBlock {
[self showPickerWithTitle:title dataSourceArr:dataSourceArr selectIndex:selectIndex isAutoSelect:NO resultBlock:resultBlock];
}
#pragma mark - 2.
+ (void)showPickerWithTitle:(NSString *)title
dataSourceArr:(NSArray *)dataSourceArr
selectIndex:(NSInteger)selectIndex
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(BRStringResultModelBlock)resultBlock {
//
BRStringPickerView *strPickerView = [[BRStringPickerView alloc]init];
strPickerView.pickerMode = BRStringPickerComponentSingle;
strPickerView.title = title;
strPickerView.dataSourceArr = dataSourceArr;
strPickerView.selectIndex = selectIndex;
strPickerView.isAutoSelect = isAutoSelect;
strPickerView.resultModelBlock = resultBlock;
//
[strPickerView show];
}
#pragma mark - 3.
+ (void)showMultiPickerWithTitle:(NSString *)title
dataSourceArr:(NSArray *)dataSourceArr
selectIndexs:(NSArray <NSNumber *>*)selectIndexs
resultBlock:(BRStringResultModelArrayBlock)resultBlock {
[self showMultiPickerWithTitle:title dataSourceArr:dataSourceArr selectIndexs:selectIndexs isAutoSelect:NO resultBlock:resultBlock];
}
#pragma mark - 4.
+ (void)showMultiPickerWithTitle:(NSString *)title
dataSourceArr:(NSArray *)dataSourceArr
selectIndexs:(NSArray <NSNumber *>*)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(BRStringResultModelArrayBlock)resultBlock {
//
BRStringPickerView *strPickerView = [[BRStringPickerView alloc]init];
strPickerView.pickerMode = BRStringPickerComponentMulti;
strPickerView.title = title;
strPickerView.dataSourceArr = dataSourceArr;
strPickerView.selectIndexs = selectIndexs;
strPickerView.isAutoSelect = isAutoSelect;
strPickerView.resultModelArrayBlock = resultBlock;
//
[strPickerView show];
}
#pragma mark - 5.
+ (void)showLinkagePickerWithTitle:(nullable NSString *)title
dataSourceArr:(nullable NSArray *)dataSourceArr
selectIndexs:(nullable NSArray <NSNumber *> *)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(nullable BRStringResultModelArrayBlock)resultBlock {
//
BRStringPickerView *strPickerView = [[BRStringPickerView alloc]init];
strPickerView.pickerMode = BRStringPickerComponentLinkage;
strPickerView.title = title;
strPickerView.dataSourceArr = dataSourceArr;
strPickerView.selectIndexs = selectIndexs;
strPickerView.isAutoSelect = isAutoSelect;
strPickerView.resultModelArrayBlock = resultBlock;
//
[strPickerView show];
}
#pragma mark -
- (instancetype)initWithPickerMode:(BRStringPickerMode)pickerMode {
if (self = [super init]) {
self.pickerMode = pickerMode;
}
return self;
}
#pragma mark -
- (void)handlerPickerData {
if (self.dataSourceArr.count == 0) {
_dataSourceException = YES;
}
id item = [self.dataSourceArr firstObject];
if (self.pickerMode == BRStringPickerComponentSingle) {
_dataSourceException = [item isKindOfClass:[NSArray class]];
} else if (self.pickerMode == BRStringPickerComponentMulti) {
_dataSourceException = [item isKindOfClass:[NSString class]];
} else if (self.pickerMode == BRStringPickerComponentLinkage) {
_dataSourceException = ![item isKindOfClass:[BRResultModel class]];
}
if (_dataSourceException) {
NSAssert(!_dataSourceException, @"数据源异常!请检查选择器数据源的格式");
return;
}
//
if (self.pickerMode == BRStringPickerComponentSingle) {
self.mDataSourceArr = self.dataSourceArr;
NSInteger selectIndex = 0;
if (self.selectIndex > 0 && self.selectIndex < self.mDataSourceArr.count) {
selectIndex = self.selectIndex;
} else {
if (self.mSelectValue) {
id item = [self.mDataSourceArr firstObject];
if ([item isKindOfClass:[BRResultModel class]]) {
for (NSInteger i = 0; i < self.mDataSourceArr.count; i++) {
BRResultModel *model = self.mDataSourceArr[i];
if ([model.value isEqualToString:self.mSelectValue]) {
selectIndex = i;
break;
}
}
} else {
if ([self.mDataSourceArr containsObject:self.mSelectValue]) {
selectIndex = [self.mDataSourceArr indexOfObject:self.mSelectValue];
}
}
}
}
self.selectIndex = selectIndex;
} else if (self.pickerMode == BRStringPickerComponentMulti) {
self.mDataSourceArr = self.dataSourceArr;
NSMutableArray *selectIndexs = [[NSMutableArray alloc]init];
for (NSInteger i = 0; i < self.mDataSourceArr.count; i++) {
NSArray *itemArr = self.mDataSourceArr[i];
NSInteger row = 0;
if (self.selectIndexs.count > 0) {
if (i < self.selectIndexs.count) {
NSInteger index = [self.selectIndexs[i] integerValue];
row = ((index > 0 && index < itemArr.count) ? index : 0);
}
} else {
if (self.mSelectValues.count > 0 && i < self.mSelectValues.count) {
NSString *value = self.mSelectValues[i];
id item = [itemArr firstObject];
if ([item isKindOfClass:[BRResultModel class]]) {
for (NSInteger j = 0; j < itemArr.count; j++) {
BRResultModel *model = itemArr[j];
if ([model.value isEqualToString:value]) {
row = j;
break;
}
}
} else {
if ([itemArr containsObject:value]) {
row = [itemArr indexOfObject:value];
}
}
}
}
[selectIndexs addObject:@(row)];
}
self.selectIndexs = [selectIndexs copy];
} else if (self.pickerMode == BRStringPickerComponentLinkage) {
NSMutableArray *selectIndexs = [[NSMutableArray alloc]init];
NSMutableArray *mDataSourceArr = [[NSMutableArray alloc]init];
BRResultModel *selectModel = nil;
BOOL hasNext = YES;
NSInteger i = 0;
NSMutableArray *dataArr = [self.dataSourceArr mutableCopy];
do {
NSArray *nextArr = [self getNextDataArr:dataArr selectModel:selectModel];
// numberOfComponents key parentKey
if (nextArr.count == 0 || i > self.numberOfComponents - 1) {
hasNext = NO;
break;
}
NSInteger selectIndex = 0;
if (self.selectIndexs.count > i && [self.selectIndexs[i] integerValue] < nextArr.count) {
selectIndex = [self.selectIndexs[i] integerValue];
}
selectModel = nextArr[selectIndex];
[selectIndexs addObject:@(selectIndex)];
[mDataSourceArr addObject:nextArr];
i++;
} while (hasNext);
self.selectIndexs = [selectIndexs copy];
self.mDataSourceArr = [mDataSourceArr copy];
}
}
- (NSArray <BRResultModel *>*)getNextDataArr:(NSArray *)dataArr selectModel:(BRResultModel *)selectModel {
NSMutableArray *tempArr = [[NSMutableArray alloc]init];
// parentKey = @"-1"
NSString *key = selectModel ? selectModel.key : @"-1";
for (BRResultModel *model in dataArr) {
if ([model.parentKey isEqualToString:key]) {
[tempArr addObject:model];
}
}
return [tempArr copy];
}
#pragma mark -
- (UIPickerView *)pickerView {
if (!_pickerView) {
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
_pickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, self.pickerStyle.titleBarHeight + pickerHeaderViewHeight, self.keyView.bounds.size.width, self.pickerStyle.pickerHeight)];
_pickerView.backgroundColor = self.pickerStyle.pickerColor;
_pickerView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
_pickerView.dataSource = self;
_pickerView.delegate = self;
}
return _pickerView;
}
#pragma mark - UIPickerViewDataSource
// 1. pickerView
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
switch (self.pickerMode) {
case BRStringPickerComponentSingle:
return 1;
break;
case BRStringPickerComponentMulti:
case BRStringPickerComponentLinkage:
return self.mDataSourceArr.count;
break;
default:
break;
}
}
// 2. pickerView
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
switch (self.pickerMode) {
case BRStringPickerComponentSingle:
return self.mDataSourceArr.count;
break;
case BRStringPickerComponentMulti:
case BRStringPickerComponentLinkage:
{
NSArray *itemArr = self.mDataSourceArr[component];
return itemArr.count;
}
break;
default:
break;
}
}
#pragma mark - UIPickerViewDelegate
// 3. pickerView
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view {
// 1. row
UILabel *label = (UILabel *)view;
if (!label) {
label = [[UILabel alloc]init];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = self.pickerStyle.pickerTextFont;
label.textColor = self.pickerStyle.pickerTextColor;
//
label.adjustsFontSizeToFitWidth = YES;
//
label.minimumScaleFactor = 0.5f;
}
if (self.pickerMode == BRStringPickerComponentSingle) {
id item = self.mDataSourceArr[row];
if ([item isKindOfClass:[BRResultModel class]]) {
BRResultModel *model = (BRResultModel *)item;
label.text = model.value;
} else {
label.text = item;
}
} else if (self.pickerMode == BRStringPickerComponentMulti || self.pickerMode == BRStringPickerComponentLinkage) {
NSArray *itemArr = self.mDataSourceArr[component];
id item = [itemArr objectAtIndex:row];
if ([item isKindOfClass:[BRResultModel class]]) {
BRResultModel *model = (BRResultModel *)item;
label.text = model.value;
} else {
label.text = item;
}
}
// 2.
[self.pickerStyle setupPickerSelectRowStyle:pickerView titleForRow:row forComponent:component];
return label;
}
// 4. pickerView
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
switch (self.pickerMode) {
case BRStringPickerComponentSingle:
{
self.selectIndex = row;
// changeModelBlock
if (self.changeModelBlock) {
self.changeModelBlock([self getResultModel]);
}
// resultModelBlock
if (self.isAutoSelect) {
if (self.resultModelBlock) {
self.resultModelBlock([self getResultModel]);
}
}
}
break;
case BRStringPickerComponentMulti:
{
if (component < self.selectIndexs.count) {
NSMutableArray *mutableArr = [self.selectIndexs mutableCopy];
[mutableArr replaceObjectAtIndex:component withObject:@(row)];
self.selectIndexs = [mutableArr copy];
}
// changeModelArrayBlock
if (self.changeModelArrayBlock) {
self.changeModelArrayBlock([self getResultModelArr]);
}
// resultModelArrayBlock
if (self.isAutoSelect) {
if (self.resultModelArrayBlock) {
self.resultModelArrayBlock([self getResultModelArr]);
}
}
}
break;
case BRStringPickerComponentLinkage:
{
if (component < self.selectIndexs.count) {
NSMutableArray *selectIndexs = [[NSMutableArray alloc]init];
for (NSInteger i = 0; i < self.selectIndexs.count; i++) {
if (i < component) {
[selectIndexs addObject:self.selectIndexs[i]];
} else if (i == component) {
[selectIndexs addObject:@(row)];
} else {
[selectIndexs addObject:@(0)];
}
}
self.selectIndexs = [selectIndexs copy];
}
//
[self reloadData];
// changeModelArrayBlock
if (self.changeModelArrayBlock) {
self.changeModelArrayBlock([self getResultModelArr]);
}
// resultModelArrayBlock
if (self.isAutoSelect) {
if (self.resultModelArrayBlock) {
self.resultModelArrayBlock([self getResultModelArr]);
}
}
}
break;
default:
break;
}
}
#pragma mark -
- (BRResultModel *)getResultModel {
id item = self.selectIndex < self.mDataSourceArr.count ? self.mDataSourceArr[self.selectIndex] : nil;
if ([item isKindOfClass:[BRResultModel class]]) {
BRResultModel *model = (BRResultModel *)item;
model.index = self.selectIndex;
return model;
} else {
BRResultModel *model = [[BRResultModel alloc]init];
model.index = self.selectIndex;
model.value = item;
return model;
}
}
#pragma mark -
- (NSArray *)getResultModelArr {
NSMutableArray *resultModelArr = [[NSMutableArray alloc]init];
for (NSInteger i = 0; i < self.mDataSourceArr.count; i++) {
NSInteger index = [self.selectIndexs[i] integerValue];
NSArray *dataArr = self.mDataSourceArr[i];
id item = index < dataArr.count ? dataArr[index] : nil;
if ([item isKindOfClass:[BRResultModel class]]) {
BRResultModel *model = (BRResultModel *)item;
model.index = index;
[resultModelArr addObject:model];
} else {
BRResultModel *model = [[BRResultModel alloc]init];
model.index = index;
model.value = item;
[resultModelArr addObject:model];
}
}
return [resultModelArr copy];
}
//
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
return self.pickerStyle.rowHeight;
}
#pragma mark -
- (void)reloadData {
// 1.
[self handlerPickerData];
// 2.
[self.pickerView reloadAllComponents];
// 3.
if (self.pickerMode == BRStringPickerComponentSingle) {
[self.pickerView selectRow:self.selectIndex inComponent:0 animated:NO];
} else if (self.pickerMode == BRStringPickerComponentMulti || self.pickerMode == BRStringPickerComponentLinkage) {
for (NSInteger i = 0; i < self.selectIndexs.count; i++) {
NSNumber *index = [self.selectIndexs objectAtIndex:i];
[self.pickerView selectRow:[index integerValue] inComponent:i animated:NO];
}
}
}
- (void)addPickerToView:(UIView *)view {
// 1.
if (view) {
// view view 使
[view setNeedsLayout];
[view layoutIfNeeded];
self.frame = view.bounds;
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
CGFloat pickerFooterViewHeight = self.pickerFooterView ? self.pickerFooterView.bounds.size.height : 0;
self.pickerView.frame = CGRectMake(0, pickerHeaderViewHeight, view.bounds.size.width, view.bounds.size.height - pickerHeaderViewHeight - pickerFooterViewHeight);
[self addSubview:self.pickerView];
} else {
// iOS16 pickerView frame
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
self.pickerView.frame = CGRectMake(0, self.pickerStyle.titleBarHeight + pickerHeaderViewHeight, self.keyView.bounds.size.width, self.pickerStyle.pickerHeight);
[self.alertView addSubview:self.pickerView];
}
// 线
if (self.pickerStyle.clearPickerNewStyle) {
[self.pickerStyle addSeparatorLineView:self.pickerView];
}
// 2.
[self reloadData];
__weak typeof(self) weakSelf = self;
self.doneBlock = ^{
// block
if (weakSelf.pickerMode == BRStringPickerComponentSingle) {
if (weakSelf.resultModelBlock) {
weakSelf.resultModelBlock([weakSelf getResultModel]);
}
} else if (weakSelf.pickerMode == BRStringPickerComponentMulti || weakSelf.pickerMode == BRStringPickerComponentLinkage) {
if (weakSelf.resultModelArrayBlock) {
weakSelf.resultModelArrayBlock([weakSelf getResultModelArr]);
}
}
};
[super addPickerToView:view];
}
#pragma mark -
- (void)addSubViewToPicker:(UIView *)customView {
[self.pickerView addSubview:customView];
}
#pragma mark -
- (void)show {
[self addPickerToView:nil];
}
#pragma mark -
- (void)dismiss {
[self removePickerFromView:nil];
}
#pragma mark - setter
- (void)setPlistName:(NSString *)plistName {
NSString *path = [[NSBundle mainBundle] pathForResource:plistName ofType:nil];
if (path && path.length > 0) {
self.dataSourceArr = [[NSArray alloc] initWithContentsOfFile:path];
}
}
- (void)setSelectValue:(NSString *)selectValue {
self.mSelectValue = selectValue;
}
- (void)setSelectValues:(NSArray<NSString *> *)selectValues {
self.mSelectValues = selectValues;
}
#pragma mark - getter
- (NSArray *)mDataSourceArr {
if (!_mDataSourceArr) {
_mDataSourceArr = [NSArray array];
}
return _mDataSourceArr;
}
- (NSArray<NSNumber *> *)selectIndexs {
if (!_selectIndexs) {
_selectIndexs = [NSArray array];
}
return _selectIndexs;
}
- (NSArray<NSString *> *)mSelectValues {
if (!_mSelectValues) {
_mSelectValues = [NSArray array];
}
return _mSelectValues;
}
- (NSInteger)numberOfComponents {
if (_numberOfComponents <= 0) {
_numberOfComponents = 3;
}
return _numberOfComponents;
}
@end