update
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
+191
@@ -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
|
||||
+571
@@ -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
|
||||
Reference in New Issue
Block a user