Modify status bar, navigation bar color and text color on iOS

During the development process, we always encounter special requirements of one kind or another, such as displaying a special style on a designated page, which is completely different from the style of the entire app. There are many ways to solve this. Today I will record one of them. study Exchange. Please correct me if there is anything wrong. If you have a better solution, you are welcome to exchange and learn.

1. Only change the status bar color

1. First set the View controller-based status bar appearance in info.plist and set its value to YES.

2. Rewrite the system method - preferredStatusBarStyle on the page where the status bar color needs to be modified.

// 仅当前页面状态栏文字颜色 - 系统方法
- (UIStatusBarStyle)preferredStatusBarStyle {
    
    
    if (self.isLightStyle) {
    
    
        // 白色
        return UIStatusBarStyleLightContent;
    }else{
    
    
        // 黑色
        if (@available(iOS 13.0, *)) {
    
    
            return UIStatusBarStyleDarkContent;
        } else {
    
    
            return UIStatusBarStyleDefault; //黑色, 默认值
        }
    }
}

3. Manually trigger preferredStatusBarStyle to update the status bar color

If you rely on returned data to determine the status bar color, you can call the following method to manually trigger preferredStatusBarStyle

// 手动触发 preferredStatusBarStyle 更新状态栏颜色
[self setNeedsStatusBarAppearanceUpdate];



2. Change the status bar and navigation bar colors at the same time

1. Set the style when it will be displayed. Restore the original style when it is about to disappear.

/// 导航栏背景颜色,准备2个颜色,是应对渐变颜色
@interface ZBWebViewVC ()
@property (nonatomic, copy) NSString *navColorOne;
@property (nonatomic, copy) NSString *navColorTwo;

@property (nonatomic, strong) UIView *statusBar;
@property (nonatomic, assign) BOOL isLightStyle;
@end


@implementation ZBWebViewVC

- (void)viewWillAppear:(BOOL)animated {
    
    
    [super viewWillAppear:animated];
    //设置显示样式,也可以返回数据后调用此方法,根据返回数据决定颜色
    [self updateNavColor:@"#ffffff" second:nil fontColor:@"#000000"];
    // 手动触发 preferredStatusBarStyle 更新状态栏颜色
	[self setNeedsStatusBarAppearanceUpdate];
}

//页面消失,还原导航条颜色
- (void)viewWillDisappear:(BOOL)animated {
    
    
    [super viewWillDisappear:animated];

    //恢复webView状态栏为白色
    if (@available(iOS 13.0, *)) {
    
    
        if ([[UIApplication sharedApplication].keyWindow.subviews containsObject:self.statusBar]) {
    
    
            [self.statusBar removeFromSuperview];
        }
    } else {
    
    
        UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
        if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
    
    
            statusBar.backgroundColor = UIColor.clearColor;
        }
    }
}

/// 更新状态栏颜色
- (void)updateStatusBarStyleIsWhite:(BOOL)isWhite{
    
    
    //修改隐藏导航栏后,状态栏颜色还原
    UIColor *bgColor = UIColor.whiteColor;
    if (self.navColorOne.length && !isWhite) {
    
    
        bgColor = [UIColor colorWithHexString:self.navColorOne];
    }
    if (@available(iOS 13.0, *)) {
    
    
        if (![[UIApplication sharedApplication].keyWindow.subviews containsObject:self.statusBar]) {
    
    
            [[UIApplication sharedApplication].keyWindow addSubview:self.statusBar];
        }
        self.statusBar.backgroundColor = bgColor;
    } else {
    
    
        UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
        if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
    
    
            statusBar.backgroundColor = bgColor;
        }
    }
}

/// 配置导航条、文字颜色
/// @param first 第一种颜色,例 白色:#ffffff
/// @param second 第二种颜色,例 黑色:#000000
/// @param fontColor title颜色,例 黑色:#000000
- (void)updateNavColor:(NSString *)first second:(NSString *)second fontColor:(NSString *)fontColor{
    
    
    UIColor *topleftColor = [UIColor colorWithHexString:first];
    UIColor *bottomrightColor = second ? [UIColor colorWithHexString:second] : topleftColor;
    UIColor *fColor;
    
    if (self.isLightStyle) {
    
    
        [self.btnLeftOne setImage:[UIImage imageNamed:@"nav_back_white"] forState:UIControlStateNormal];
        [self.btnLeftTwo setImage:[UIImage imageNamed:@"nav_close_white"] forState:UIControlStateNormal];
        
        [self.btnRightOne setImage:[UIImage imageNamed:@"caigoudannew_white"] forState:UIControlStateNormal];
        [self.btnRightTwo setImage:[UIImage imageNamed:@"share_white"] forState:UIControlStateNormal];
        
        fColor = fontColor ? [UIColor colorWithHexString:fontColor] : UIColor.whiteColor;
        [self updateStatusBarStyleIsWhite:NO];
    }else{
    
    
        [self.btnLeftOne setImage:[UIImage imageNamed:@"nav_back_black"] forState:UIControlStateNormal];
        [self.btnLeftTwo setImage:[UIImage imageNamed:@"nav_close_black"] forState:UIControlStateNormal];
        
        [self.btnRightOne setImage:[UIImage imageNamed:@"caigoudannew"] forState:UIControlStateNormal];
        [self.btnRightTwo setImage:[UIImage imageNamed:@"share_black"] forState:UIControlStateNormal];
        
        fColor = fontColor ? [UIColor colorWithHexString:fontColor] : UIColor.blackColor;
        [self updateStatusBarStyleIsWhite:YES];
    }
    
    // 设置导航条背景图
    UIImage *bgImg = [UIImage gradientColorImageFromColors:@[topleftColor, bottomrightColor] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(XYYScreenW, kNavBarHeight)];
    if (@available(iOS 13.0, *)) {
    
    
        UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
        [appearance configureWithOpaqueBackground];
        appearance.backgroundImage = bgImg;
        appearance.titleTextAttributes = @{
    
    NSForegroundColorAttributeName:fColor, NSFontAttributeName:[UIFont systemFontOfSize:17]};
        self.navigationController.navigationBar.standardAppearance = appearance;
        self.navigationController.navigationBar.scrollEdgeAppearance = appearance;
    }else{
    
    
        self.navigationController.navigationBar.titleTextAttributes =
        @{
    
    NSForegroundColorAttributeName:fColor, NSFontAttributeName:[UIFont systemFontOfSize:17]};
    }
    [self.navigationController.navigationBar setBackgroundImage:bgImg forBarMetrics:UIBarMetricsDefault];
}

#pragma mark - lazy
- (UIView *)statusBar{
    
    
    if (!_statusBar) {
    
    
        if (@available(iOS 13.0, *)) {
    
    
            _statusBar = [[UIView alloc] initWithFrame:[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame];
        }
    }
    return _statusBar;
}

Note: I wrote the buttons on the navigation bar here myself. When you use them, you can modify them appropriately according to your own needs.

2. When changes are needed, call the -updateNavColor:second:fontColor: method to change the style.

[self updateNavColor:self.navColorOne second:self.navColorTwo fontColor:fontColor];







3. Dependent extension class: UIImage+GradientColor

UIImage+GradientColor.h

#import <UIKit/UIKit.h>

///渐变方向
typedef NS_ENUM(NSUInteger, GradientType) {
    
    
    GradientTypeTopToBottom = 0,//从上到小
    GradientTypeLeftToRight = 1,//从左到右
    GradientTypeUpleftToLowright = 2,//左上到右下
    GradientTypeUprightToLowleft = 3,//右上到左下
};

@interface UIImage (GradientColor)
/// 通过一组颜色生成一个渐变色的图片
+ (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize;

/// 通过颜色来生成一个纯色图片
+ (UIImage*)imageWithColor:(UIColor*)color;

@end

UIImage+GradientColor.m

#import "UIImage+GradientColor.h"

@implementation UIImage (GradientColor)
/// 通过一组颜色生成一个渐变色的图片
+ (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize {
    
    
    if (colors.count == 0) {
    
    
        return nil;
    }
    NSMutableArray *ar = [NSMutableArray array];
    for(UIColor *c in colors) {
    
    
        [ar addObject:(id)c.CGColor];
    }
    UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);
    CGPoint start;
    CGPoint end;
    switch (gradientType) {
    
    
        case GradientTypeTopToBottom:
            start = CGPointMake(0.0, 0.0);
            end = CGPointMake(0.0, imgSize.height);
            break;
        case GradientTypeLeftToRight:
            start = CGPointMake(0.0, 0.0);
            end = CGPointMake(imgSize.width, 0.0);
            break;
        case GradientTypeUpleftToLowright:
            start = CGPointMake(0.0, 0.0);
            end = CGPointMake(imgSize.width, imgSize.height);
            break;
        case GradientTypeUprightToLowleft:
            start = CGPointMake(imgSize.width, 0.0);
            end = CGPointMake(0.0, imgSize.height);
            break;
        default:
            break;
    }
    CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    CGGradientRelease(gradient);
    CGContextRestoreGState(context);
//    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.
    UIGraphicsEndImageContext();
    return image;
}

//通过颜色来生成一个纯色图片
+ (UIImage*)imageWithColor:(UIColor*)color{
    
    
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

@end


4. Preview the completed effect:

Insert image description here
Insert image description here
Insert image description here

Guess you like

Origin blog.csdn.net/biyuhuaping/article/details/122740292