随着 iOS 13 的到来,statusBar的视图不再可以通过槽访问:
value(forKey: "statusBar") as? UIView
由于:
由于未捕获的异常而终止应用程序 “ NSInternalInconsistencyException”,原因:“应用程序名为-statusBar或 UIApplication上的-statusBarWindow:由于不再有状态栏或状态栏窗口,因此必须更改此代码。使用 而是在窗口场景上使用statusBarManager对象。'
但是由于keyWindow?.windowScene?.statusBarManager
似乎不包含任何与其相关的内容,因此尚不清楚应如何使用它来更改颜色。
我正在编译具有(iOS 10,*)兼容性的代码,所以我打算继续使用UIKit。
关于这个主题有什么想法吗?
答案 0 :(得分:32)
您可以添加一些条件或使用第一个条件。只需为UIApplication创建一些扩展即可。
extension UIApplication {
var statusBarUIView: UIView? {
if #available(iOS 13.0, *) {
let tag = 38482
let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
if let statusBar = keyWindow?.viewWithTag(tag) {
return statusBar
} else {
guard let statusBarFrame = keyWindow?.windowScene?.statusBarManager?.statusBarFrame else { return nil }
let statusBarView = UIView(frame: statusBarFrame)
statusBarView.tag = tag
keyWindow?.addSubview(statusBarView)
return statusBarView
}
} else if responds(to: Selector(("statusBar"))) {
return value(forKey: "statusBar") as? UIView
} else {
return nil
}
}
}
更新:对不起,我没有足够的时间在实际项目中对其进行测试,但是它可以在“ Hello world”应用程序中使用。您可以阅读有关keyWindow和statusBarFrame的更多信息,以使其变得更好。
extension UIApplication {
var statusBarUIView: UIView? {
if #available(iOS 13.0, *) {
let tag = 3848245
let keyWindow = UIApplication.shared.connectedScenes
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows.first
if let statusBar = keyWindow?.viewWithTag(tag) {
return statusBar
} else {
let height = keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
let statusBarView = UIView(frame: height)
statusBarView.tag = tag
statusBarView.layer.zPosition = 999999
keyWindow?.addSubview(statusBarView)
return statusBarView
}
} else {
if responds(to: Selector(("statusBar"))) {
return value(forKey: "statusBar") as? UIView
}
}
return nil
}
}
答案 1 :(得分:4)
我以前遇到过此问题。当我使用XCode 11和Swift 5.0运行此代码时,我的应用程序崩溃了。
上一个代码:-
if #available(iOS 13.0, *) {
let statusBar = UIView(frame: UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? CGRect.zero)
statusBar.backgroundColor = UIColor.init(red: 243/250, green: 243/250, blue: 243/250, alpha: 1)
UIApplication.shared.keyWindow?.addSubview(statusBar)
} else {
UIApplication.shared.statusBarView?.backgroundColor = UIColor.init(red: 243/250, green: 243/250, blue: 243/250, alpha: 1)
}
仅更改为:-
return Ok(response);
现在我的问题解决了。编码愉快。
答案 2 :(得分:2)
不幸的是,Apple不赞成使用上述提到的访问状态栏和编辑其属性的方法。您将必须使用StatusBarManager
的{{1}}对象。以下方法适用于iOS 13及更高版本:
WindowScene
答案 3 :(得分:2)
这在Swift 5中对我有用
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 13, *)
{
let statusBar = UIView(frame: (UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame)!)
statusBar.backgroundColor = #colorLiteral(red: 0.2346, green: 0.3456, blue: 0.5677, alpha: 1)
UIApplication.shared.keyWindow?.addSubview(statusBar)
} else {
// ADD THE STATUS BAR AND SET A CUSTOM COLOR
let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to:#selector(setter: UIView.backgroundColor)) {
statusBar.backgroundColor = #colorLiteral(red: 0.2346, green: 0.3456, blue: 0.5677, alpha: 1)
}
UIApplication.shared.statusBarStyle = .lightContent
}
}
答案 4 :(得分:1)
if (@available(iOS 13, *))
{
UIView *statusBar = [[UIView alloc]initWithFrame:[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame] ;
statusBar.backgroundColor = [UIColor redColor];
[[UIApplication sharedApplication].keyWindow addSubview:statusBar];
}
答案 5 :(得分:1)
对于像我这样仍在使用它的人,这是大多数投票答案的ObjC版本:
创建UIApplication的类别并将其添加到您的项目中:
@implementation UIApplication (iOS13PorcoDiDio)
- (UIView*) statusBar
{
if([UIDevice getOSVersion] >= 13)
{
const NSUInteger k_TAG_STATUSBAR = 38482458385;
UIView * vStatusBar = [[UIApplication sharedApplication].keyWindow viewWithTag:k_TAG_STATUSBAR];
if(vStatusBar != nil)
return vStatusBar;
else {
UIView *vStatusBar = [[UIView alloc] initWithFrame:[UIApplication sharedApplication].statusBarFrame];
[vStatusBar setTag:k_TAG_STATUSBAR];
[[UIApplication sharedApplication].keyWindow addSubview:vStatusBar];
return vStatusBar;
}
} else if([UIApplication respondsToSelector:@selector(statusBar)])
return (UIView*)[UIApplication sharedApplication].statusBar;
else
return nil;
}
@end
答案 6 :(得分:1)
答案 7 :(得分:1)
经过测试,并且100%为我工作
func statusBarColorChange(){
if #available(iOS 13.0, *) {
let statusBar = UIView(frame: UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? CGRect.zero)
statusBar.backgroundColor = AppThemeColor
statusBar.tag = 100
UIApplication.shared.keyWindow?.addSubview(statusBar)
} else {
let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView
statusBar?.backgroundColor = AppThemeColor
}
}
}
从键窗口中删除状态栏
func removeStatusBar(){
if #available(iOS 13.0, *) {
UIApplication.shared.keyWindow?.viewWithTag(100)?.removeFromSuperview()
}
}
在viewDidLoad
和viewWillAppear
中调用函数
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
removeStatusBar()
statusBarColorChange()
}
override func viewDidLoad() {
super.viewDidLoad()
removeStatusBar()
statusBarColorChange()
}
答案 8 :(得分:1)
KeyWindow在iOS13中已弃用。 您可以将此扩展名用于 swift 5 和 iOS 13至顶部
extension UIApplication {
var statusBarUIView: UIView? {
if #available(iOS 13.0, *) {
let tag = 3848245
let keyWindow: UIWindow? = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
if let statusBar = keyWindow?.viewWithTag(tag) {
return statusBar
} else {
let height = keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
let statusBarView = UIView(frame: height)
statusBarView.tag = tag
statusBarView.layer.zPosition = 999999
keyWindow?.addSubview(statusBarView)
return statusBarView
}
} else {
if responds(to: Selector(("statusBar"))) {
return value(forKey: "statusBar") as? UIView
}
}
return nil
}
}
并在 AppDelegate 类的 didFinishLaunchingWithOptions 中使用它,例如:
UIApplication.shared.statusBarUIView?.backgroundColor = .red(any color)
答案 9 :(得分:0)
对于Swift 5.0,我这样做是为了更改背景颜色,
if #available(iOS 13.0, *) {
let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
// Reference - https://stackoverflow.com/a/57899013/7316675
let statusBar = UIView(frame: window?.windowScene?.statusBarManager?.statusBarFrame ?? CGRect.zero)
statusBar.backgroundColor = .white
window?.addSubview(statusBar)
} else {
UIApplication.shared.statusBarView?.backgroundColor = .white
UIApplication.shared.statusBarStyle = .lightContent
}
https://medium.com/@trivediniki94/surprises-after-upgrading-to-xcode-11-ios-13-b52b36e05fa8
答案 10 :(得分:0)
答案 11 :(得分:0)
Use this Extension:
extension UINavigationController {
func setStatusBar(backgroundColor: UIColor) {
let statusBarFrame: CGRect
if #available(iOS 13.0, *) {
statusBarFrame = view.window?.windowScene?.statusBarManager?.statusBarFrame ?? CGRect.zero
} else {
statusBarFrame = UIApplication.shared.statusBarFrame
}
let statusBarView = UIView(frame: statusBarFrame)
statusBarView.backgroundColor = backgroundColor
view.addSubview(statusBarView)
}}
答案 12 :(得分:-1)
您可以尝试
if (@available(iOS 13, *))
{
UIView *_localStatusBar = [[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager performSelector:@selector(createLocalStatusBar)];
statusBar = [_localStatusBar performSelector:@selector(statusBar)];
}
else
{
statusBar = [[UIApplication sharedApplication] valueForKey:@"statusBar"];
}
答案 13 :(得分:-1)
我这样做,可以获取statusBar,但设置statusBar backgroundColor不起作用
UIView *statusBar;
if (@available(iOS 13, *)) {
UIView *_localStatusBar = [[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager performSelector:@selector(createLocalStatusBar)];
statusBar = [_localStatusBar performSelector:@selector(statusBar)];
}
else {
statusBar = [[UIApplication sharedApplication] valueForKey:@"statusBar"];
}
if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
statusBar.backgroundColor = [UIColor redColor];
}
答案 14 :(得分:-1)
这是我见过的最好的答案。。干杯
if #available(iOS 13.0, *) {
let app = UIApplication.shared
let statusBarHeight: CGFloat = app.statusBarFrame.size.height
let statusbarView = UIView()
statusbarView.backgroundColor = ColorPalette.grayChateau
view.addSubview(statusbarView)
statusbarView.translatesAutoresizingMaskIntoConstraints = false
statusbarView.heightAnchor
.constraint(equalToConstant: statusBarHeight).isActive = true
statusbarView.widthAnchor
.constraint(equalTo: view.widthAnchor, multiplier: 1.0).isActive = true
statusbarView.topAnchor
.constraint(equalTo: view.topAnchor).isActive = true
statusbarView.centerXAnchor
.constraint(equalTo: view.centerXAnchor).isActive = true
} else {
let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView
statusBar?.backgroundColor = UIColor.red
}