123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485 |
- //
- // 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`是iOS9以后新增的地区代码,如:CN 代表中国,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];
- }
- }
- @end
|