iOS小技能:设置状态栏背景颜色(图片)
ios 设置 图片 技能 颜色 背景 状态栏
2023-06-13 09:11:18 时间
引言
- 设置状态栏背景颜色的解决方案:
使用新的API 【statusBarManager】
- 通过安全区域高度判断是否IphoneX之后的机型:
if ([UIApplication sharedApplication].delegate.window.safeAreaInsets.bottom > 0)
I 状态栏背景颜色的适配方案
- 问题
[Bugly] Trapped uncaught exception 'NSInternalInconsistencyException', reason: 'App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.'
- 旧代码
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
1.1 使用新的API 【statusBarManager】
- 解决方案:使用
keyWindow.windowScene.statusBarManager
if (@available(iOS 13.0, *)) {
UIView *statusBar = [[UIView alloc]initWithFrame:[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame] ;
statusBar.backgroundColor = color;
[[UIApplication sharedApplication].keyWindow addSubview:statusBar];
} else {
// Fallback on earlier versions
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
statusBar.backgroundColor = color;
}
}
statusBarFrame
CGRect rectStatus = [[UIApplication sharedApplication] statusBarFrame];
//API_DEPRECATED("Use the statusBarManager property of the window scene instead.", ios(2.0, 13.0));
if (@available(iOS 13.0, *)) {
rectStatus = [UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame;
}
1.2 适配特色场景:状态是有透明或者半透明的效果的场景
- 补充:如果整个项目的状态栏(电池栏)都是有颜色的,并且都是不透明的,上面这个方法完全可以应付。但是如果有状态是有透明或者半透明的效果,上面这个方法还是不能胜任,越透明越明显;经过一番查找,终于发现问题:
- 问题:
1、iOS 13之前,可以通过valueForKey 获取UIApplication的statusBar,因为UIApplication是单例,因此,在iOS 12,通过:
[[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"]
拿到的statusBar永远是同一个对象。2、iOS 13之后,因为苹果不允许使用KVC的valueForKey访问私有属性。通过上面的代码获取statusBar时,发现每次每次获取都调用 alloc:init的方法,重新生成一个statusBar;然后添加到UIApplication的keyWindow上,再设置背景颜色。因此这个方法多次调用就会创建多份statusBar,造成内存开销不说,想设置状态栏为为透明,根本没效果。
解决办法:既然定位到问题所在,办法就是保证iOS 13 之后,每次也都能拿到有去只有一个对象。方法有很多,我的方法代码如下:使用 static 配合 gcd
HSSingletonM(QCTStatusBarTool);
+ (void)setStatusBarBackgroundColor4ios13:(UIColor *)color {
static UIView *statusBar = nil;
static dispatch_once_t onceToken;
if (@available(iOS 13.0, *)) { //iOS 13不允许使用valueForKey、setValue: forKey获取和设置私有属性;
dispatch_once(&onceToken, ^{
statusBar = [[UIView alloc] initWithFrame:[UIApplication sharedApplication].statusBarFrame];
[[UIApplication sharedApplication].keyWindow addSubview:statusBar];
});
} else {
statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
}
if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
statusBar.backgroundColor = color;
}
}
II 通过安全区域高度判断是否IphoneX之后的机型
#define isIphoneX [QCT_Common isiPhoneX]
+ (BOOL)isiPhoneX {
if (@available(iOS 11.0, *)) {
if ([UIApplication sharedApplication].delegate.window.safeAreaInsets.bottom > 0) {//iphoneX横屏
return YES;
} else {
return NO;
}
} else {
return NO;
}
}
///*状态栏和导航栏总高度*/
#define kStatusBarHeight (CGFloat)(isIphoneX?(88.0):(64.0))
/*iPhoneX的状态栏高度差值*/
#define kPtatusBarHeight (CGFloat)(isIphoneX?(24.0):(0))
/*底部安全区域远离高度*/
#define kDtatusBarHeight (CGFloat)(isIphoneX?(34.0):(0))
2.1 应用场景1:自定义导航栏内容
导航栏显示公告和标题
navView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, kWidth, kStatusBarHeight)];
2.2 应用场景2:设置状态栏背景图片
/**
用于设置状态栏的背景图片
*/
@property (weak, nonatomic) UIButton *imgLable;
- (UIButton *)imgLable{
if (nil == _imgLable) {
UIButton *tmpView = [[UIButton alloc]init];
_imgLable = tmpView;
tmpView.userInteractionEnabled = NO;
[tmpView setBackgroundImage:[UIImage imageNamed:@"img_daiban_topbg_top"] forState:UIControlStateNormal];
[self addSubview:_imgLable];
__weak __typeof__(self) weakSelf = self;
[_imgLable mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(weakSelf).offset(0);
make.top.equalTo(weakSelf).offset(0);
make.height.mas_equalTo(kStatusBarHeight);
// make.top.equalTo.offset(kAdjustRatio(44));
}];
}
return _imgLable;
}
推荐使用自动布局,和使用API获取高度
#define kstatusBarH [[UIApplication sharedApplication] statusBarFrame].size.height
#define knavHeight self.navigationController.navigationBar.frame.size.height
//获取状态栏的高度
CGFloat statusHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
NSLog(@"状态栏高度:%f",statusHeight);
//获取导航栏的高度
CGFloat navHeight = self.navigationController.navigationBar.frame.size.height;
NSLog(@"导航栏高度:%f",navHeight);
//获取tabBar的高度
//1.在tabBarController中使用(你的继承自UITabBarController的VC)
CGFloat tabBarHeight = self.tabBar.frame.size.height;
NSLog(@"tabBar高度:%f",tabBarHeight);
//2.在非tabBarController中使用
UITabBarController *tabBarVC = [[UITabBarController alloc] init];//(这儿取你当前tabBarVC的实例)
CGFloat tabBarHeight = tabBarVC.tabBar.frame.size.height;
NSLog(@"tabBar高度:%f",tabBarHeight);
see also
- iOS13适配暗黑模式方案:1、设置app不支持Dark Mode 2、制定深色模式开发规范 https://blog.csdn.net/z929118967/article/details/104293041
相关文章
- iOS 获取本地图片尺寸_ios图片处理软件
- Hbuilder用自有证书打包 ios App上架AppStore流程
- iOS https(SSL/TLS)数据捕获
- HBuilder X 连接苹果手机(IOS)详细教程。Windows: 连接iOS手机调试项目
- IOS – OPenGL ES 设置图像亮度 GPUImageBrightnessFilter
- iOS开发之——浅谈网络图片处理机制
- IOS – OpenGL ES 设置图像滤镜 GPUImageSoftEleganceFilter
- IOS – OpenGL ES 设置图像模糊 GPUImageFastBlurFilter
- 【 iOS 应用开发 】 UIKit 控件 ( UIView 属性 | storyboard 设置 | 模拟器 | 拖线关联 | tag | 软键盘操作 | 颜色值 | 代码生成控件 | 动画设置 )
- iOS 14 支持 WebP,WPJAM Basic 4.5 也支持在 Safari 14 上 WebP 图片
- ios APP最新打包上线教程
- iOS设备是否越狱的判断代码详解手机开发
- iOS tableView下拉图片放大详解手机开发
- iOS 字符串常用判定库详解手机开发
- IOS设置图片水印代码详解手机开发
- iOS发送邮件的代码详解手机开发
- iOS与Linux:新老技术的融合(ios与linux的关系)
- iOS 15界面曝光:安卓味儿越来越浓
- 前谷歌员工曝Chrome曾放弃了跟iOS 15 Safari中一个相似的新设计
- Linux下安装iOS:解决方案(linux安装ios)
- 基于Linux环境下iOS应用开发实践(linux下开发ios)
- 微信 iOS 版 8.0.10 正式版发布
- 使用iOS就能操作Oracle数据库(ios上oracle)
- Reddit用户发现CSAM检测中使用的苹果NeuralHash算法隐藏在iOS 14.3中