iOS 修改状态栏、导航条颜色及文字颜色

嚴華  金牌会员 | 2022-6-24 17:36:06 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 687|帖子 687|积分 2061

在开发过程中,我们总是遇到这样那样的特殊要求,比如在指定页面展示特殊的样式,完全异于整个app的风格,为此有很多办法解决,今天我来记录其中一种,我们互相学习交流。如有不妥还请指正,如有更好的方案,欢迎交流学习。
  
修改状态栏、导航条颜色及文字颜色



一、只改变状态栏颜色

1、首先在info.plist设置View controller-based status bar appearance,并将其值设置为YES。

2、在需要修改状态栏颜色的页面重写系统方法-preferredStatusBarStyle

  1. // 仅当前页面状态栏文字颜色 - 系统方法
  2. - (UIStatusBarStyle)preferredStatusBarStyle {
  3.     if (self.isLightStyle) {
  4.         // 白色
  5.         return UIStatusBarStyleLightContent;
  6.     }else{
  7.         // 黑色
  8.         if (@available(iOS 13.0, *)) {
  9.             return UIStatusBarStyleDarkContent;
  10.         } else {
  11.             return UIStatusBarStyleDefault; //黑色, 默认值
  12.         }
  13.     }
  14. }
复制代码
3、手动触发 preferredStatusBarStyle 更新状态栏颜色

如果依赖返回数据来决定状态栏颜色,可以调用下面方法手动触发preferredStatusBarStyle
  1. // 手动触发 preferredStatusBarStyle 更新状态栏颜色
  2. [self setNeedsStatusBarAppearanceUpdate];
复制代码



二、同时改变状态栏、导航条颜色

1、将要显示时设置样式。将要消失时恢复原有样式。

  1. /// 导航栏背景颜色,准备2个颜色,是应对渐变颜色
  2. @interface ZBWebViewVC ()
  3. @property (nonatomic, copy) NSString *navColorOne;
  4. @property (nonatomic, copy) NSString *navColorTwo;
  5. @property (nonatomic, strong) UIView *statusBar;
  6. @property (nonatomic, assign) BOOL isLightStyle;
  7. @end
  8. @implementation ZBWebViewVC
  9. - (void)viewWillAppear:(BOOL)animated {
  10.     [super viewWillAppear:animated];
  11.     //设置显示样式,也可以返回数据后调用此方法,根据返回数据决定颜色
  12.     [self updateNavColor:@"#ffffff" second:nil fontColor:@"#000000"];
  13.     // 手动触发 preferredStatusBarStyle 更新状态栏颜色
  14.         [self setNeedsStatusBarAppearanceUpdate];
  15. }
  16. //页面消失,还原导航条颜色
  17. - (void)viewWillDisappear:(BOOL)animated {
  18.     [super viewWillDisappear:animated];
  19.     //恢复webView状态栏为白色
  20.     if (@available(iOS 13.0, *)) {
  21.         if ([[UIApplication sharedApplication].keyWindow.subviews containsObject:self.statusBar]) {
  22.             [self.statusBar removeFromSuperview];
  23.         }
  24.     } else {
  25.         UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
  26.         if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
  27.             statusBar.backgroundColor = UIColor.clearColor;
  28.         }
  29.     }
  30. }
  31. /// 更新状态栏颜色
  32. - (void)updateStatusBarStyleIsWhite:(BOOL)isWhite{
  33.     //修改隐藏导航栏后,状态栏颜色还原
  34.     UIColor *bgColor = UIColor.whiteColor;
  35.     if (self.navColorOne.length && !isWhite) {
  36.         bgColor = [UIColor colorWithHexString:self.navColorOne];
  37.     }
  38.     if (@available(iOS 13.0, *)) {
  39.         if (![[UIApplication sharedApplication].keyWindow.subviews containsObject:self.statusBar]) {
  40.             [[UIApplication sharedApplication].keyWindow addSubview:self.statusBar];
  41.         }
  42.         self.statusBar.backgroundColor = bgColor;
  43.     } else {
  44.         UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
  45.         if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
  46.             statusBar.backgroundColor = bgColor;
  47.         }
  48.     }
  49. }
  50. /// 配置导航条、文字颜色
  51. /// @param first 第一种颜色,例 白色:#ffffff
  52. /// @param second 第二种颜色,例 黑色:#000000
  53. /// @param fontColor title颜色,例 黑色:#000000
  54. - (void)updateNavColor:(NSString *)first second:(NSString *)second fontColor:(NSString *)fontColor{
  55.     UIColor *topleftColor = [UIColor colorWithHexString:first];
  56.     UIColor *bottomrightColor = second ? [UIColor colorWithHexString:second] : topleftColor;
  57.     UIColor *fColor;
  58.    
  59.     if (self.isLightStyle) {
  60.         [self.btnLeftOne setImage:[UIImage imageNamed:@"nav_back_white"] forState:UIControlStateNormal];
  61.         [self.btnLeftTwo setImage:[UIImage imageNamed:@"nav_close_white"] forState:UIControlStateNormal];
  62.         
  63.         [self.btnRightOne setImage:[UIImage imageNamed:@"caigoudannew_white"] forState:UIControlStateNormal];
  64.         [self.btnRightTwo setImage:[UIImage imageNamed:@"share_white"] forState:UIControlStateNormal];
  65.         
  66.         fColor = fontColor ? [UIColor colorWithHexString:fontColor] : UIColor.whiteColor;
  67.         [self updateStatusBarStyleIsWhite:NO];
  68.     }else{
  69.         [self.btnLeftOne setImage:[UIImage imageNamed:@"nav_back_black"] forState:UIControlStateNormal];
  70.         [self.btnLeftTwo setImage:[UIImage imageNamed:@"nav_close_black"] forState:UIControlStateNormal];
  71.         
  72.         [self.btnRightOne setImage:[UIImage imageNamed:@"caigoudannew"] forState:UIControlStateNormal];
  73.         [self.btnRightTwo setImage:[UIImage imageNamed:@"share_black"] forState:UIControlStateNormal];
  74.         
  75.         fColor = fontColor ? [UIColor colorWithHexString:fontColor] : UIColor.blackColor;
  76.         [self updateStatusBarStyleIsWhite:YES];
  77.     }
  78.    
  79.     // 设置导航条背景图
  80.     UIImage *bgImg = [UIImage gradientColorImageFromColors:@[topleftColor, bottomrightColor] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(XYYScreenW, kNavBarHeight)];
  81.     if (@available(iOS 13.0, *)) {
  82.         UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
  83.         [appearance configureWithOpaqueBackground];
  84.         appearance.backgroundImage = bgImg;
  85.         appearance.titleTextAttributes = @{NSForegroundColorAttributeName:fColor, NSFontAttributeName:[UIFont systemFontOfSize:17]};
  86.         self.navigationController.navigationBar.standardAppearance = appearance;
  87.         self.navigationController.navigationBar.scrollEdgeAppearance = appearance;
  88.     }else{
  89.         self.navigationController.navigationBar.titleTextAttributes =
  90.         @{NSForegroundColorAttributeName:fColor, NSFontAttributeName:[UIFont systemFontOfSize:17]};
  91.     }
  92.     [self.navigationController.navigationBar setBackgroundImage:bgImg forBarMetrics:UIBarMetricsDefault];
  93. }
  94. #pragma mark - lazy
  95. - (UIView *)statusBar{
  96.     if (!_statusBar) {
  97.         if (@available(iOS 13.0, *)) {
  98.             _statusBar = [[UIView alloc] initWithFrame:[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame];
  99.         }
  100.     }
  101.     return _statusBar;
  102. }
复制代码
注:我这里的导航条上的按钮是自己写了一下,你用的时候,可以根据自己的需要适当修改。


2、在需要改变时,调用-updateNavColor:second:fontColor:方法,改变样式

  1. [self updateNavColor:self.navColorOne second:self.navColorTwo fontColor:fontColor];
复制代码








三、 依赖的扩展类:UIImage+GradientColor

UIImage+GradientColor.h
  1. #import <UIKit/UIKit.h>
  2. ///渐变方向
  3. typedef NS_ENUM(NSUInteger, GradientType) {
  4.     GradientTypeTopToBottom = 0,//从上到小
  5.     GradientTypeLeftToRight = 1,//从左到右
  6.     GradientTypeUpleftToLowright = 2,//左上到右下
  7.     GradientTypeUprightToLowleft = 3,//右上到左下
  8. };
  9. @interface UIImage (GradientColor)
  10. /// 通过一组颜色生成一个渐变色的图片
  11. + (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize;
  12. /// 通过颜色来生成一个纯色图片
  13. + (UIImage*)imageWithColor:(UIColor*)color;
  14. @end
复制代码
UIImage+GradientColor.m
  1. #import "UIImage+GradientColor.h"
  2. @implementation UIImage (GradientColor)
  3. /// 通过一组颜色生成一个渐变色的图片
  4. + (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize {
  5.     if (colors.count == 0) {
  6.         return nil;
  7.     }
  8.     NSMutableArray *ar = [NSMutableArray array];
  9.     for(UIColor *c in colors) {
  10.         [ar addObject:(id)c.CGColor];
  11.     }
  12.     UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);
  13.     CGContextRef context = UIGraphicsGetCurrentContext();
  14.     CGContextSaveGState(context);
  15.     CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
  16.     CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);
  17.     CGPoint start;
  18.     CGPoint end;
  19.     switch (gradientType) {
  20.         case GradientTypeTopToBottom:
  21.             start = CGPointMake(0.0, 0.0);
  22.             end = CGPointMake(0.0, imgSize.height);
  23.             break;
  24.         case GradientTypeLeftToRight:
  25.             start = CGPointMake(0.0, 0.0);
  26.             end = CGPointMake(imgSize.width, 0.0);
  27.             break;
  28.         case GradientTypeUpleftToLowright:
  29.             start = CGPointMake(0.0, 0.0);
  30.             end = CGPointMake(imgSize.width, imgSize.height);
  31.             break;
  32.         case GradientTypeUprightToLowleft:
  33.             start = CGPointMake(imgSize.width, 0.0);
  34.             end = CGPointMake(0.0, imgSize.height);
  35.             break;
  36.         default:
  37.             break;
  38.     }
  39.     CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
  40.     UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  41.     CGGradientRelease(gradient);
  42.     CGContextRestoreGState(context);
  43. //    CGColorSpaceRelease(colorSpace); 解决闪退 Assertion failed: (!space->is_singleton), function color_space_dealloc, file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Quartz2D/Quartz2D-1033.1/CoreGraphics/ColorSpaces/color-space.c, line 102.
  44.     UIGraphicsEndImageContext();
  45.     return image;
  46. }
  47. //通过颜色来生成一个纯色图片
  48. + (UIImage*)imageWithColor:(UIColor*)color{
  49.     CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
  50.     UIGraphicsBeginImageContext(rect.size);
  51.     CGContextRef context = UIGraphicsGetCurrentContext();
  52.     CGContextSetFillColorWithColor(context, [color CGColor]);
  53.     CGContextFillRect(context, rect);
  54.     UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  55.     UIGraphicsEndImageContext();
  56.     return image;
  57. }
  58. @end
复制代码


四、预览完成效果:





免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表