在开发过程中,我们总是遇到这样那样的特殊要求,比如在指定页面展示特殊的样式,完全异于整个app的风格,为此有很多办法解决,今天我来记录其中一种,我们互相学习交流。如有不妥还请指正,如有更好的方案,欢迎交流学习。
修改状态栏、导航条颜色及文字颜色
一、只改变状态栏颜色
1、首先在info.plist设置View controller-based status bar appearance,并将其值设置为YES。
2、在需要修改状态栏颜色的页面重写系统方法-preferredStatusBarStyle
- // 仅当前页面状态栏文字颜色 - 系统方法
- - (UIStatusBarStyle)preferredStatusBarStyle {
- if (self.isLightStyle) {
- // 白色
- return UIStatusBarStyleLightContent;
- }else{
- // 黑色
- if (@available(iOS 13.0, *)) {
- return UIStatusBarStyleDarkContent;
- } else {
- return UIStatusBarStyleDefault; //黑色, 默认值
- }
- }
- }
复制代码 3、手动触发 preferredStatusBarStyle 更新状态栏颜色
如果依赖返回数据来决定状态栏颜色,可以调用下面方法手动触发preferredStatusBarStyle
- // 手动触发 preferredStatusBarStyle 更新状态栏颜色
- [self setNeedsStatusBarAppearanceUpdate];
复制代码
二、同时改变状态栏、导航条颜色
1、将要显示时设置样式。将要消失时恢复原有样式。
- /// 导航栏背景颜色,准备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;
- }
复制代码 注:我这里的导航条上的按钮是自己写了一下,你用的时候,可以根据自己的需要适当修改。
2、在需要改变时,调用-updateNavColor:second:fontColor:方法,改变样式
- [self updateNavColor:self.navColorOne second:self.navColorTwo fontColor:fontColor];
复制代码
三、 依赖的扩展类: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
复制代码
四、预览完成效果:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |