From 3351fcbbf4aa1b558b5925122a066dba838928d8 Mon Sep 17 00:00:00 2001 From: renbo Date: Fri, 25 Sep 2020 17:00:21 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8D=E9=80=89=E6=8B=A9=E5=99=A8iO?= =?UTF-8?q?S14=E7=9A=84=E6=A0=B7=E5=BC=8F=EF=BC=9A#189=E3=80=81#191?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BRPickerView/Base/BRBaseView.h | 2 +- BRPickerView/Base/BRPickerStyle.h | 6 + BRPickerView/Base/BRPickerStyle.m | 109 ++++++++++++++++++ .../DatePickerView/BRDatePickerView+BR.h | 3 - .../DatePickerView/BRDatePickerView+BR.m | 58 ---------- .../DatePickerView/BRDatePickerView.m | 7 +- 6 files changed, 122 insertions(+), 63 deletions(-) diff --git a/BRPickerView/Base/BRBaseView.h b/BRPickerView/Base/BRBaseView.h index 568144a..6d3cd90 100644 --- a/BRPickerView/Base/BRBaseView.h +++ b/BRPickerView/Base/BRBaseView.h @@ -35,7 +35,7 @@ typedef void(^BRResultBlock)(void); /** accessory view below picker view. default is nil */ @property (nullable, nonatomic, strong) UIView *pickerFooterView; -/** 选择结果的回调(框架内部使用) */ +/** 选择结果的回调(组件内部使用)*/ @property (nullable, nonatomic, copy) BRResultBlock doneBlock; /** 弹框视图(使用场景:可以在 alertView 上添加选择器的自定义背景视图) */ diff --git a/BRPickerView/Base/BRPickerStyle.h b/BRPickerView/Base/BRPickerStyle.h index bb6cc87..05ccd56 100644 --- a/BRPickerView/Base/BRPickerStyle.h +++ b/BRPickerView/Base/BRPickerStyle.h @@ -181,6 +181,9 @@ typedef NS_ENUM(NSInteger, BRBorderStyle) { /** 设置 picker 中间选中行文本的字体。暂不支持日期选择器前4种类型 */ @property (nullable, nonatomic, strong) UIFont *selectRowTextFont; +/** 隐藏 中间选中行 系统默认的样式(iOS14以上才有),默认为 YES */ +@property (nonatomic, assign) BOOL hideSelectRowSystemStyle; + /** 设置 picker 的高度,系统默认高度为 216 */ @property (nonatomic, assign) CGFloat pickerHeight; @@ -225,6 +228,9 @@ typedef NS_ENUM(NSInteger, BRBorderStyle) { + (instancetype)pickerStyleWithDoneBtnImage:(nullable UIImage *)doneBtnImage; +/** 设置选择器中间选中行的样式(组件内部使用)*/ +- (void)setupPickerSelectRowStyle:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component; + @end NS_ASSUME_NONNULL_END diff --git a/BRPickerView/Base/BRPickerStyle.m b/BRPickerView/Base/BRPickerStyle.m index f8a6b48..2f70948 100644 --- a/BRPickerView/Base/BRPickerStyle.m +++ b/BRPickerView/Base/BRPickerStyle.m @@ -15,6 +15,13 @@ @implementation BRPickerStyle +- (instancetype)init { + if (self = [super init]) { + self.hideSelectRowSystemStyle = YES; + } + return self; +} + /// 设置默认样式 - (UIColor *)maskColor { @@ -333,4 +340,106 @@ + (instancetype)pickerStyleWithDoneBtnImage:(UIImage *)doneBtnImage { return customStyle; } + +#pragma mark - 设置选择器中间选中行的样式 +- (void)setupPickerSelectRowStyle:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { + // 1.设置分割线的颜色 + for (UIView *subView in pickerView.subviews) { + if (subView && [subView isKindOfClass:[UIView class]] && subView.frame.size.height <= 1) { + subView.backgroundColor = self.separatorColor; + } + } + + // 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 (self.hideSelectRowSystemStyle && contentView) { + if (@available(iOS 14.0, *)) { + // 隐藏最上层圆角矩形背景视图 + id lastView = subviews.lastObject; + if (lastView && [lastView isKindOfClass:[UIView class]]) { + UIView *rectBgView = (UIView *)lastView; + rectBgView.backgroundColor = [UIColor clearColor]; + } + + // 清除iOS14上选择器的默认样式 + [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; + } + } + }); + } +} + +// 遍历设置子视图(修改在 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]; + } +} + @end diff --git a/BRPickerView/DatePickerView/BRDatePickerView+BR.h b/BRPickerView/DatePickerView/BRDatePickerView+BR.h index 7a604e5..4470663 100644 --- a/BRPickerView/DatePickerView/BRDatePickerView+BR.h +++ b/BRPickerView/DatePickerView/BRDatePickerView+BR.h @@ -55,9 +55,6 @@ NS_ASSUME_NONNULL_BEGIN /** 设置日期单位 */ - (NSArray *)setupPickerUnitLabel:(UIPickerView *)pickerView unitArr:(NSArray *)unitArr; -/** 设置选择器中间选中行的样式 */ -- (void)setupPickerSelectRowStyle:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component; - - (NSString *)getYearNumber:(NSInteger)year; - (NSString *)getMDHMSNumber:(NSInteger)number; diff --git a/BRPickerView/DatePickerView/BRDatePickerView+BR.m b/BRPickerView/DatePickerView/BRDatePickerView+BR.m index a521723..ae5a82f 100644 --- a/BRPickerView/DatePickerView/BRDatePickerView+BR.m +++ b/BRPickerView/DatePickerView/BRDatePickerView+BR.m @@ -442,64 +442,6 @@ - (NSArray *)setupPickerUnitLabel:(UIPickerView *)pickerView unitArr:(NSArray *) return [tempArr copy]; } -#pragma mark - 设置选择器中间选中行的样式 -- (void)setupPickerSelectRowStyle:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { - // 1.设置分割线的颜色 - for (UIView *subView in pickerView.subviews) { - if (subView && [subView isKindOfClass:[UIView class]] && subView.frame.size.height <= 1) { - subView.backgroundColor = self.pickerStyle.separatorColor; - } - } - - // 2.设置选择器中间选中行的背景颜色 - if (self.pickerStyle.selectRowColor) { - UIView *contentView = nil; - NSArray *subviews = pickerView.subviews; - if (subviews.count > 0) { - id obj = subviews.firstObject; - if (obj && [obj isKindOfClass:[UIView class]]) { - contentView = (UIView *)obj; - } - } - 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.pickerStyle.selectRowColor; - } - } - } - - // 3.设置选择器中间选中行的字体颜色/字体大小 - if (self.pickerStyle.selectRowTextColor || self.pickerStyle.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.pickerStyle.selectRowTextColor) { - selectLabel.textColor = self.pickerStyle.selectRowTextColor; - } - if (self.pickerStyle.selectRowTextFont) { - selectLabel.font = self.pickerStyle.selectRowTextFont; - } - } - }); - } -} - - (NSString *)getYearNumber:(NSInteger)year { NSString *yearString = [NSString stringWithFormat:@"%@", @(year)]; if (self.isNumberFullName) { diff --git a/BRPickerView/DatePickerView/BRDatePickerView.m b/BRPickerView/DatePickerView/BRDatePickerView.m index 2402b54..29d2143 100755 --- a/BRPickerView/DatePickerView/BRDatePickerView.m +++ b/BRPickerView/DatePickerView/BRDatePickerView.m @@ -675,7 +675,7 @@ - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forC label.text = [self pickerView:pickerView titleForRow:row forComponent:component]; // 2.设置选择器中间选中行的样式 - [self setupPickerSelectRowStyle:pickerView titleForRow:row forComponent:component]; + [self.pickerStyle setupPickerSelectRowStyle:pickerView titleForRow:row forComponent:component]; return label; } @@ -1271,6 +1271,11 @@ - (void)reloadData { if (self.minuteInterval > 1) { self.datePicker.minuteInterval = self.minuteInterval; } + + // 重新设置 datePicker 的宽高(在iOS14里,需要先 datePickerMode,再设置 frame,否则 frame 不会生效) + CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0; + self.datePicker.frame = CGRectMake(0, self.pickerStyle.titleBarHeight + pickerHeaderViewHeight, self.keyView.bounds.size.width, self.pickerStyle.pickerHeight); + // 3.滚动到选择的日期 [self.datePicker setDate:self.mSelectDate animated:NO]; } else if (self.style == BRDatePickerStyleCustom) {