问题
With the arrival of iOS 13 statusBar's view is no longer accessible trough:
value(forKey: "statusBar") as? UIView
Due to:
Terminating app due to 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.'
But it's not clear how it should be used for changing colours as keyWindow?.windowScene?.statusBarManager does not appear to contain anything related to it.
I'm compiling my code with (iOS 10, *) compatibility, so I intend to continue using UIKit.
Any ideas regarding this subject?
回答1:
You can add some conditions or use first one. Just create some extension for 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
}
}
}
回答2:
I have encountered this issue before. My application got crash while I run this code using XCode 11 and Swift 5.0.
Previous Code:-
UIApplication.shared.statusBarView?.backgroundColor = UIColor.init(red: 243/250, green: 243/250, blue: 243/250, alpha: 1)
Just Changed to:-
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)
}
Now my problem solved. Happy coding.
回答3:
you can try this
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"];
}
回答4:
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:
this is an ObjC version of most voted answer for those like me who are still using it:
create a category of UIApplication and add it to your project:
@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:
This is the best answer I have ever seen.. Cheers
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
}
回答7:
for swift 5.0 I've done this to change background color,
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
}
回答8:
I do this, can get statusBar,but set statusBar backgroundColor do not work
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];
}
来源:https://stackoverflow.com/questions/56651245/how-to-change-the-status-bar-background-color-and-text-color-on-ios-13