gpt4 book ai didi

How do I prevent iOS 13's Dark Mode from changing the text color in my app's status bar?(如何防止iOS13的S深色模式更改应用程序状态栏中的文本颜色?)

转载 作者:bug小助手 更新时间:2023-10-25 15:31:41 27 4
gpt4 key购买 nike



My navigation bar has a white backgroundColor and my status bar uses the dark textColor. When a user changes the iOS theme to Dark Mode, the status bar changes to white text on a white background. As a result, I can't see anything. How can I disable this change for my app?

我的导航栏有一个白色的backgroundColor和我的状态栏使用深色textColor。当用户将iOS主题更改为深色模式时,状态栏将更改为白色背景上的白色文本。结果,我什么也看不见。如何禁用我的应用的此更改?


更多回答

It sounds like you don't wish to support darkMode at all. You can opt out of supporting darkMode. That's been covered here.

听起来你根本不想支持黑暗模式。您可以选择不支持暗模式。这里已经介绍了这一点。

yes You right, but > here < - where? I do not see link

是的,你说得对,但是>这里<-哪里?我看不到链接

I meant Stack Overflow. Search on opting out of dark mode.

我是说堆栈溢出。在选择退出黑暗模式时进行搜索。

> here < and > here <

>这里<和>这里<

Even if you implement the suggestions in those posts you will likely still have problems with the status bar unless you override its default behaviour already in your app.

即使你实现了这些帖子中的建议,你很可能仍然会在状态栏上遇到问题,除非你覆盖了应用程序中已经存在的默认行为。

优秀答案推荐

iOS 13 Solution(s)


UINavigationController is a subclass of UIViewController! (who knew 🙃)

UINavigationController是UIView控制器的子类!(谁知道🙃)


Therefore, when presenting view controllers embedded in navigation controllers, you're not really presenting the embedded view controllers; you're presenting the navigation controllers! UINavigationController, as a subclass of UIViewController, inherits preferredStatusBarStyle and childForStatusBarStyle, which you can set as desired.

因此,当呈现嵌入在导航控制器中的视图控制器时,您实际上并没有呈现嵌入的视图控制器;您呈现的是导航控制器!UINavigationController作为UIView控制器的子类,继承了您可以根据需要设置的首选项StatusBarStyle和Child ForStatusBarStyle。


Any of the following methods should work:

以下任何一种方法都应该有效:



  1. Opt out of Dark Mode entirely



    • In your info.plist, add the following property:

      • Key - UIUserInterfaceStyle (aka. "User Interface Style")

      • Value - Light





  2. Override preferredStatusBarStyle within UINavigationController



    • preferredStatusBarStyle (doc) - The preferred status bar style for the view controller



    • Subclass or extend UINavigationController


        class MyNavigationController: UINavigationController {
      override var preferredStatusBarStyle: UIStatusBarStyle {
      .lightContent
      }
      }

      OR


        extension UINavigationController {
      open override var preferredStatusBarStyle: UIStatusBarStyle {
      .lightContent
      }
      }





  3. Override childForStatusBarStyle within UINavigationController



    • childForStatusBarStyle (doc) - Called when the system needs the view controller to use for determining status bar style

    • According to Apple's documentation,



    "If your container view controller derives its status bar style from one of its child view controllers, [override this property] and return that child view controller. If you return nil or do not override this method, the status bar style for self is used. If the return value from this method changes, call the setNeedsStatusBarAppearanceUpdate() method."




    • In other words, if you don't implement solution 3 here, the system will fall back to solution 2 above.



    • Subclass or extend UINavigationController


        class MyNavigationController: UINavigationController {
      override var childForStatusBarStyle: UIViewController? {
      topViewController
      }
      }

      OR


        extension UINavigationController {    
      open override var childForStatusBarStyle: UIViewController? {
      topViewController
      }
      }



    • You can return any view controller you'd like above. I recommend one of the following:



      • topViewController (of UINavigationController) (doc) - The view controller at the top of the navigation stack

      • visibleViewController (of UINavigationController) (doc) - The view controller associated with the currently visible view in the navigation interface (hint: this can include "a view controller that was presented modally on top of the navigation controller itself")






Note: If you decide to subclass UINavigationController, remember to apply that class to your nav controllers through the identity inspector in IB.

注意:如果您决定将UINavigationControler子类化,请记住通过IB中的身份检查器将该类应用于您的NAV控制器。


Edits: Strikethrough edits were made to remove extensions as a suggested answer. Other developers noted that they stopped working in Xcode 11.4 and Apple's documentation discourages the use of this ambiguous behavior.

编辑:删除线编辑是为了删除作为建议答案的扩展。其他开发人员指出,他们在Xcode 11.4中停止了工作,Apple的文档不鼓励使用这种模棱两可的行为。


P.S. My code uses Swift 5.1 syntax 😎

附注:我的代码使用SWIFT 5.1语法😎



If you set the UIViewControllerBasedStatusBarAppearance key in your app's info.plist to YES, you can override the status bar style in your currently presented view controller:

如果您在应用程序的info.plist中将UIViewControllerBasedStatusBarspections键设置为yes,则可以覆盖当前呈现的视图控制器中的状态栏样式:



override var preferredStatusBarStyle: UIStatusBarStyle {
if #available(iOS 13, *) {
return .darkContent
} else {
return .default
}
}


and call the setNeedsStatusBarAppearanceUpdate() method

并调用setNeedsStatusBarEmeraranceUpdate()方法



You can write extension to UIStatusBarStyle:

您可以向UIStatusBarStyle写入扩展名:



extension UIStatusBarStyle {
static var black: UIStatusBarStyle {
if #available(iOS 13.0, *) {
return .darkContent
}
return .default
}
}


And then you can easily use in your ViewControllers:

然后,您可以轻松地在您的ViewController中使用:



override var preferredStatusBarStyle: UIStatusBarStyle {
.black
}


You can try to make your navigation bar always light

您可以尝试使导航栏始终亮起



if #available(iOS 13.0, *) {
navigationController?.navigationBar.overrideUserInterfaceStyle = .light
}


I have done something like this.

我曾经做过这样的事情。



I have toggler function wich toggles Status bar style depending on View Controller displayed

我有切换功能,可以根据显示的视图控制器来切换状态栏样式



func toggleLight() {
self.navigationBar.barTintColor = AppColors.White

isDarkStyle = false
setNeedsStatusBarAppearanceUpdate()

}


and here is most important part

这是最重要的部分



override var preferredStatusBarStyle: UIStatusBarStyle {

if #available(iOS 13.0, *) {
return isDarkStyle ? .lightContent : .darkContent
}
return isDarkStyle ? .lightContent : .default
}


Where isDarkStyle represents navigation bar background colour dark or light. If it is dark then text (content) should be light, if it is light than text (content) should be default or from iOS 13 dark.

其中,isDarkStyle表示导航栏的背景色、深色或浅色。如果它是深色的,那么文本(内容)应该是浅色的,如果它是浅色的,那么文本(内容)应该是默认的或来自iOS 13的深色。



To sum up: .lightContent, .darkContent displays independent of Dark Mode as it is supposed to do. While .default is susceptible to Dark Mode changes!

总而言之:.lightContent,.darkContent独立于黑暗模式显示,就像它应该做的那样。而.Default易受黑暗模式更改的影响!



If you're using a UINavigationController, override the preferredStatusBarStyle in an extension (or your own subclass) like this (just overriding preferredStatusBarStyle in your view controllers won't work):

如果您使用的是UINavigationController,那么在一个扩展(或您自己的子类)中重写operredStatusBarStyle,如下所示(只是重写视图控制器中的preciredStatusBarStyle将不起作用):



extension UINavigationController {
override open var preferredStatusBarStyle: UIStatusBarStyle {
guard #available(iOS 13, *) else {
return .default
}
return .darkContent
}
}


And as Frank said, UIViewControllerBasedStatusBarAppearance must be set to YES in your info.plist

正如Frank所说,必须在info.plist中将UIViewControllerBasedStatusBarance设置为yes



There are two ways to solve this problem. Define the childViewControllerForStatusBarStyle function in the UINavigationController descendant class:

有两种方法可以解决这个问题。在UINavigationController子类中定义子ViewControllerForStatusBarStyle函数:



@interface MyNavigationController : UINavigationController
...
@end

@implementation MyNavigationController
...
- (UIViewController *)childViewControllerForStatusBarStyle
{
return self.topViewController;
}
...
@end


After that, you need to add the function preferredStatusBarStyle for each controller.

在此之后,您需要为每个控制器添加首选项StatusBarStyle函数。



The second option is to define the preferredStatusBarStyle function for all controllers. But this function should not be located in the root controller, but in the descendant class of the UINavigationController.

第二个选项是为所有控制器定义首选状态BarStyle函数。但此函数不应位于根控制器中,而应位于UINavigationController的后代类中。



@interface MyNavigationController : UINavigationController
...
@end

@implementation MyNavigationController
...
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
...
@end


However, even in this case, it is necessary to define the function preferredStatusBarStyle for all controllers that hide the navigation bar (if any).

但是,即使在这种情况下,也需要为隐藏导航栏(如果有的话)的所有控制器定义函数preciredStatusBarStyle。



This extension helps you to change the status bar text color and support also iOS 13 https://stackoverflow.com/a/59767435/10512612

此扩展可帮助您更改状态栏文本颜色,并支持iOS 13 https://stackoverflow.com/a/59767435/10512612



If anyone else finds that neither of the above answers work (as I did), there's a very specific edge-case if you have multiple windows within a UIWindowScene where it will use the topmost window rather than the key window to determine status bar appearance.

如果其他人发现上面的两个答案都不起作用(就像我一样),那么就有一个非常特殊的边缘情况--如果你在一个UIWindowScene中有多个窗口,它将使用最上面的窗口而不是键窗口来确定状态栏的外观。


So for example, if you have your key window with a windowLevel set to 1 and a secondary window with a windowLevel set to 1.1, UIKit will (for whatever reason) ask the view controllers in your secondary window for their status bar appearance rather than the ones in the key window, even though its alpha is 0.

因此,例如,如果关键点窗口的windowLevel设置为1,而辅助窗口的windowLevel设置为1.1,则UIKit将(无论出于何种原因)向辅助窗口中的视图控制器询问其状态栏外观,而不是询问关键点窗口中的控制器,即使其Alpha为0。


Our workaround was simply to only put the secondary window on a higher level when it was active, and lowering it below the key window when it was hidden.

我们的解决方法只是在辅助窗口处于活动状态时将其置于较高级别,而在隐藏时将其降低到关键点窗口下方。



Add the below two lines in info.plist

在info.plist中添加以下两行



  1. Key: Appearance , Type: string , Value: (dark/light)



  2. Key: View controller-based status bar appearance, Type: Boolean, Value: YES




then above the top status bar(Time shows above) will be in light mode.

然后,顶部状态栏(上面的时间显示)的上方将处于灯光模式。


Or copy the below code and paste in info.plist(right click on info.plist and open with Source Code)

或者复制以下代码并粘贴到info.plist中(右键单击info.plist并打开源代码)


<key>UIUserInterfaceStyle</key>
<string>light</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>

更多回答

Note that the extension method of doing override var does not work anymore in Xcode 11.4/iOS 13.4

请注意,执行覆盖var的扩展方法在Xcode11.4/iOS 13.4中不再有效

@MarcEtcheverry do you know what the alternative is for 13.4?

@MarcEtcheverry你知道13.4的替代方案是什么吗?

Subclass any of those container view controllers and override there, which is the proper way to do this. Swift extensions for ObjC classes may be implemented using ObjC categories, which never could safely override things. You could swizzle it in ObjC, but subclassing is safer.

将任何容器视图控制器子类化并在那里覆盖,这是完成此操作的正确方法。可以使用Objc类别实现对Objc类的SWIFT扩展,而Objc类别永远不能安全地覆盖对象。您可以在objc中使用它,但子类化更安全。

"If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime. This is less likely to be an issue if you’re using categories with your own classes, but can cause problems when using categories to add methods to standard Cocoa or Cocoa Touch classes". developer.apple.com/library/archive/documentation/Cocoa/…

如果在类别中声明的方法的名称与原始类中的方法相同,或者与同一类(甚至超类)上的另一个类别中的方法相同,则行为未定义在运行时使用哪个方法实现。如果将类别与自己的类一起使用,则不太可能出现问题,但当使用类别向标准Cocoa或Cocoa Touch类添加方法时,可能会导致问题。Developer.apple.com/library/archive/documentation/Cocoa/…

I worked for Darkmode (have to make it same as light mode as per Client requirement) then after finished my work just saw this that we can exclude support for darkmode just with a keyword! :D good for next time atleast..!

我为黑暗模式工作(必须根据客户的要求使其与灯光模式相同),然后在完成我的工作后,我发现我们可以通过一个关键字来排除对黑暗模式的支持!:D至少下一次很好..!

I am using both of those configurations but Dark Mode still overrides the status bar color.

我正在使用这两种配置,但深色模式仍然覆盖状态栏颜色。

@AndrewKirna Hard so say what the issue might be. Do you maybe want to post a question for that?

@AndrewKirna Hard,所以说出问题可能是什么。你想不想发布一个关于这个问题的问题?

Ok, I’ll consider posting. It seems Apple wants me to use a dynamic color for my nav bars, however, I don’t want to do that because it uses my company’s branding. I’m guessing your solution has the same problem I’m experiencing (black status bar text in light mode; white status bar text in dark mode) despite overriding preferredStatusBarStyle in each view controller. Have you built it on Xcode 11 for iOS 13?

好的,我会考虑发帖的。苹果似乎希望我的导航栏使用动态的颜色,然而,我不想这样做,因为它使用了我公司的品牌。我猜您的解决方案具有与我相同的问题(亮模式下的黑色状态栏文本;暗模式下的白色状态栏文本),尽管覆盖了每个视图控制器中的首选状态栏样式。你是在iOS13的Xcode11上构建的吗?

Yes, works perfectly for me. Are you sure you override it in the main presented view controller?

是的,对我来说很合适。您确定要在主显示的视图控制器中覆盖它吗?

Frank, I followed a bunch of links related to your link above and eventually discovered what I needed! Thanks for the help. I posted my solution below!

弗兰克,我关注了一堆与你上面的链接相关的链接,最终发现了我需要的东西!谢谢你的帮助。我在下面发布了我的解决方案!

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com