在 iOS13 上更改状态栏颜色
Posted
技术标签:
【中文标题】在 iOS13 上更改状态栏颜色【英文标题】:Change status bar colour on iOS13 【发布时间】:2020-01-23 21:59:01 【问题描述】:在 ios 13 之前,我可以使用以下代码更改状态栏颜色:
UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
statusBar.BackgroundColor = UIColor.Clear.FromHex(0x323232);
statusBar.TintColor = UIColor.White;
app.StatusBarStyle = UIStatusBarStyle.BlackOpaque;
但是,在 iOS13 上,我收到以下运行时错误
Objective-C 抛出异常。名称:NSInternalInconsistencyException 原因:应用程序在 UIApplication 上调用了 -statusBar 或 -statusBarWindow:此代码必须更改,因为不再有状态栏或状态栏窗口。改为在窗口场景中使用 statusBarManager 对象。
知道如何在 iOS13 上更改状态栏吗?
编辑:只是要指出,这是针对 Xamarin 而不是针对 Swift。澄清重复标记。
【问题讨论】:
How to change the status bar background color and text color on iOS 13?的可能重复 @Mac 这是怎么重复的?这是为了 swift,这是为了 Xamarin 它不是重复的。这里需要 xamarin ios 的解决方案。似乎需要一种设置状态栏背景颜色的新方法。但是,从苹果文档中,没有更多关于如何使用UIStatusBarManager的细节。 错误是一样的,解决方法应该是一样的,你只需要将swift代码转换为C# Xamarin代码。也就是说,我做了一个快速测试,但 KeyWindow 总是无效的,所以那个欺骗帖子的答案失败了。 @jgoldberger-MSFT 说解决方案是相同的,只是因为错误相同,考虑到这里有两个框架,这似乎有点过于简化了。 【参考方案1】:由于报错,需要在IOS 13中使用UIStatusBarManager。
如果您已将 VS 更新到最新版本(Visual Studio 2019 版本 16.3.0/Visual Studio 2019 for Mac 版本 8.3 ),您可以按如下方式更改颜色:
UIView statusBar = new UIView(UIApplication.SharedApplication.KeyWindow.WindowScene.StatusBarManager.StatusBarFrame);
statusBar.BackgroundColor = UIColor.Yellow;
UIApplication.SharedApplication.KeyWindow.AddSubview(statusBar);
否则以下方法可以使其工作。
UIView statusBar = new UIView(UIApplication.SharedApplication.StatusBarFrame);
statusBar.BackgroundColor = UIColor.Yellow;
UIApplication.SharedApplication.KeyWindow.AddSubview(statusBar);
如果视图未完全渲染,UIApplication.SharedApplication.KeyWindow
将返回 null。因此您可以在完全渲染后更改状态栏颜色。这是sample。
====================================更新=========== =======================
如果在Forms项目中,你可以试试AppDelegate.cs
中的调用方法
public override void OnActivated(UIApplication uiApplication)
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
// If VS has updated to the latest version , you can use StatusBarManager , else use the first line code
// UIView statusBar = new UIView(UIApplication.SharedApplication.StatusBarFrame);
UIView statusBar = new UIView(UIApplication.SharedApplication.KeyWindow.WindowScene.StatusBarManager.StatusBarFrame);
statusBar.BackgroundColor = UIColor.Red;
UIApplication.SharedApplication.KeyWindow.AddSubview(statusBar);
else
UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
statusBar.BackgroundColor = UIColor.Red;
UIApplication.SharedApplication.StatusBarStyle = UIStatusBarStyle.BlackOpaque;
base.OnActivated(uiApplication);
注意:
不确定这个解决方案在AppDelegate.cs
中是否始终有效,最好在Controller.cs
的方法中调用,因为从 iOS 13 开始,Apple 已经修改了 AppDelegate 的架构并添加了 SceneDelegate 进行投影。
【讨论】:
尝试访问UIApplication.SharedApplication.Windows[0]
会引发索引超出范围错误
@DavidPilkington 你试试KeyWindow
,它适用于我的项目。您可以显示在 project 中调用它的位置,AppDelegate / ViewDidLoad
方法将不起作用。也就是说,您不能直接在FinishedLaunching
或ViewDidLoad
中使用它,因为视图没有完全呈现。您应该在 ViewDidAppear
或其他一些事件中调用它,例如 Button click method 等。
UIApplication.SharedApplication.StatusBarFrame 将返回 CGRect。但在解决方案中,您正在尝试转换为 UIView。它会起作用吗?它是工作副本吗?
@VasanthRavichandran 是的,它会返回CGRect
。您之前的代码也转换为UIView
,它会起作用。我将在答案中分享我的样本。
@JohnLivermore 如果在 AppDelegate.cs
中,则不会有 ViewDidAppear
。我的共享答案基于 Xamarin.iOS 项目。 ViewDidAppear
可以在 Controller 中调用。现在你是一个Forms项目,你可以调用AppDelegate.cs
中的OnActivated
方法。我会更新答案。【参考方案2】:
如果在 UIViewController 中的 ViewDidAppear 覆盖中使用,这也有效。我之前在 ViewWillAppear 中进行了测试,即使这样也太早了,不能有一个 KeyWindow 非空:
public override void ViewDidAppear(bool animated)
base.ViewDidAppear(animated);
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
//Obj-C:
// UIView *statusBar = [[UIView alloc]initWithFrame:[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame] ;
// statusBar.backgroundColor = [UIColor redColor];
// [[UIApplication sharedApplication].keyWindow addSubview:statusBar];
// Xamarin.iOS:
UIView statusBar = new UIView(UIApplication.SharedApplication.KeyWindow.WindowScene.StatusBarManager.StatusBarFrame);
statusBar.BackgroundColor = UIColor.Red;
UIApplication.SharedApplication.KeyWindow.AddSubview(statusBar);
else
UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
statusBar.BackgroundColor = UIColor.Red;
statusBar.TintColor = UIColor.White;
UIApplication.SharedApplication.StatusBarStyle = UIStatusBarStyle.BlackOpaque;
这与重复问题中提供的解决方案相同:https://***.com/a/58028658/2913599
【讨论】:
【参考方案3】:请您尝试以下解决方案。在相同的情况下它对我来说效果很好
if (@available(iOS 13.0, *))
UIView *statusBar = [[UIView alloc]initWithFrame:[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame];
statusBar.backgroundColor = [UIColor redColor];
[[UIApplication sharedApplication].keyWindow addSubview:statusBar];
else
// Fallback on earlier versions
UIView *statusBar=[[UIApplication sharedApplication] valueForKey:@"statusBar"];
statusBar.backgroundColor = [UIColor redColor];
[statusBar setNeedsDisplay];
【讨论】:
以上是关于在 iOS13 上更改状态栏颜色的主要内容,如果未能解决你的问题,请参考以下文章