【问题标题】:Is it possible to opt-out of dark mode on iOS 13?是否可以在 iOS 13 上选择退出暗模式?
【发布时间】:2019-10-25 12:44:28
【问题描述】:

我的应用程序的很大一部分由 Web 视图组成,以提供尚未通过本机实现提供的功能。网络团队没有计划为网站实施深色主题。因此,在 iOS 13 上支持深色模式时,我的应用看起来会有点一半/一半。

是否可以选择退出暗模式支持,以便我们的应用始终显示亮模式以匹配网站主题?

【问题讨论】:

  • 在 Info.Plist 中将 UIUserInterfaceStyle 设置为 Light。见developer.apple.com/library/archive/documentation/General/…
  • 感谢您的提问 - 为我们所有人。很多应用程序要通过。这是在切换准备就绪之前保持应用正常运行所必需的。
  • import Foundation import UIKit extension UIViewController { override open func awakeFromNib() { super.awakeFromNib() if #available(iOS 13.0, *) { // 始终采用轻量级界面风格。 overrideUserInterfaceStyle = .light } } }
  • 只需在 plist 中添加 UIUserInterfaceStyle。就这么简单
  • 在将应用程序提交到应用商店时,由于 UIUserInterfaceStyle 在 Light 模式下,Apple 会接受。

标签: ios ios13 ios-darkmode


【解决方案1】:

首先,Apple's entry 与退出暗模式有关。 此链接中的内容是为 Xcode 11 和 iOS 13 编写的

通过 info.plist 文件的整个应用程序 (Xcode 12)

在 info.plist 文件中使用以下键:

UIUserInterfaceStyle

并为其赋值Light

UIUserInterfaceStyle 分配的 XML

<key>UIUserInterfaceStyle</key>
<string>Light</string>

Apple documentation for UIUserInterfaceStyle


整个应用通过构建设置中的 info.plist (Xcode 13)


通过 window 属性的整个应用窗口

您可以针对应用程序的window 变量设置overrideUserInterfaceStyle。这将适用于出现在窗口中的所有视图。这在 iOS 13 中可用,因此对于支持以前版本的应用,您必须包含可用性检查。

根据您的项目的创建方式,这可能位于 AppDelegateSceneDelegate 文件中。

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

单独的 UIViewController 或 UIView

您可以针对UIViewControllers 或UIViewoverrideUserInterfaceStyle 变量设置overrideUserInterfaceStyle。这在 iOS 13 中可用,因此对于支持以前版本的应用,您必须包含可用性检查。

斯威夫特

override func viewDidLoad() {
    super.viewDidLoad()
    // overrideUserInterfaceStyle is available with iOS 13
    if #available(iOS 13.0, *) {
        // Always adopt a light interface style.
        overrideUserInterfaceStyle = .light
    }
}

献给 Objective-C 中那些可怜的灵魂

if (@available(iOS 13.0, *)) {
        self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
}

当针对UIViewController 设置时,视图控制器及其子项采用定义的模式。

当针对UIView 设置时,视图及其子视图采用定义的模式。

Apple documentation for overrideUserInterfaceStyle


通过 SwiftUI 视图的个人视图

您可以将preferredColorScheme 设置为lightdark。提供的值将设置演示文稿的配色方案。

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Light Only")
            .preferredColorScheme(.light)
    }
}

Apple documentation for preferredColorScheme


感谢 @Aron Nelson@Raimundas Sakalauskas@NSLeader@rmaddy 改进了这个答案与他们的反馈。

【讨论】:

  • UIUserInterfaceStyle 灯在现在更新/上传您的应用程序时被阻挡。它被标记为无效的 plist 条目。 (无效的 plist 键)
  • 这不会针对 iOS SDK 12(当前最新的稳定 SDK)进行编译。有关适用于 iOS 12 SDK 的解决方案,请参阅 stackoverflow.com/a/57521901/2249485
  • 不用在每个视图控制器的viewDidLoad 中设置overrideUserInterfaceStyle,您可以在应用程序的主窗口中设置一次。如果您希望整个应用程序以一种方式运行,那就容易多了。
  • 使用#if compiler(&gt;=5.1) 代替responds(to:)setValue
  • Info.plist 中的键已更改为Appearance&lt;key&gt; Appearance&lt;/key&gt; &lt;string&gt;Light&lt;/string&gt;
【解决方案2】:

根据 Apple 关于“在 iOS 上实现暗模式”的会话(https://developer.apple.com/videos/play/wwdc2019/214/ 从 31:13 开始)可以在任何视图控制器或视图上将 overrideUserInterfaceStyle 设置为 UIUserInterfaceStyleLightUIUserInterfaceStyleDark,这将在traitCollection 中用于任何子视图或视图控制器。

正如 SeanR 已经提到的,您可以在应用的 plist 文件中将 UIUserInterfaceStyle 设置为 LightDark,以便为整个应用更改此设置。

【讨论】:

  • 如果您设置了 UIUserInterfaceStyle 键,您的应用将在 App Store 中被拒绝
  • Apple 被拒绝并显示 ITMS-90190 错误代码 forums.developer.apple.com/thread/121028
  • 拒绝的可能性最大,因为 iOS 13 SDK 尚未结束测试版。我认为一旦 Xcode 11 GM 可用,这应该会起作用。
  • @dorbeetle 这不是真的,我使用此密钥成功上传了我的应用程序,就像 1 个月前使用 Xcode 10 一样。最近发生了拒绝。这似乎是某种新的苹果战略。
  • 它仍在发生。 Xcode GM2 返回应用签名错误。 Xcode 10.3 返回:“无效的 Info.plist 键。Payload/Galileo.appInfo.plist 文件中的键 'UIUserInterfaceStyle' 无效。”
【解决方案3】:

如果您使用的不是 Xcode 11 或更高版本(即 iOS 13 或更高版本的 SDK),您的应用不会自动选择支持暗模式。因此,无需退出暗模式。

如果您使用的是 Xcode 11 或更高版本,系统会自动为您的应用启用暗模式。根据您的喜好,有两种方法可以禁用暗模式。您可以完全禁用它,也可以为任何特定的窗口、视图或视图控制器禁用它。

为您的应用完全禁用暗模式

您可以通过在应用的 Info.plist 文件中包含值为 LightUIUserInterfaceStyle 键来禁用暗模式。

这会忽略用户的偏好,并始终为您的应用应用浅色外观。

禁用窗口、视图或视图控制器的暗模式

您可以通过设置相应窗口、视图或视图控制器的overrideUserInterfaceStyle 属性来强制界面始终以浅色或深色样式显示。

视图控制器:

override func viewDidLoad() {
    super.viewDidLoad()
    /* view controller’s views and child view controllers 
     always adopt a light interface style. */
    overrideUserInterfaceStyle = .light
}

观看次数:

// The view and all of its subviews always adopt light style.
youView.overrideUserInterfaceStyle = .light

窗口:

/* Everything in the window adopts the style, 
 including the root view controller and all presentation controllers that 
 display content in that window.*/
window.overrideUserInterfaceStyle = .light

注意:Apple 强烈建议在您的应用中支持暗模式。所以, 您只能暂时禁用暗模式。

在此处阅读更多信息:Choosing a Specific Interface Style for Your iOS App

【讨论】:

  • 在 XCode 12.4 中它显示为“外观”而不是用户界面样式。
【解决方案4】:

********** Xcode 11 及更高版本最简单的方法 ***********

&lt;/dict&gt;&lt;/plist&gt;之前添加到info.plist

<key>UIUserInterfaceStyle</key>
<string>Light</string>

【讨论】:

  • 在 Xcode 10.x 上提交应用时,此解决方案将失败
【解决方案5】:

Xcode 12 和 iOS 14 更新。我已经尝试了以前的选项来选择退出暗模式,而 info.plist 文件中的这句话对我不起作用:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

现在改名为:

<key>Appearance</key>
<string>Light</string>

此设置将阻止整个应用程序中的所有暗模式。

已编辑:

修正错别字感谢@sarah

【讨论】:

  • 有点错字,应该是外观:)
【解决方案6】:

我想我已经找到了解决方案。我最初将 UIUserInterfaceStyle - Information Property ListUIUserInterfaceStyle - UIKit 拼凑在一起,但现在发现它实际上记录在 Choosing a specific interface style for your iOS app

在您的info.plist 中,将UIUserInterfaceStyle用户界面样式)设置为1UIUserInterfaceStyle.light)。

编辑:根据多甲虫的回答,UIUserInterfaceStyle 的更合适的设置可能是 Light

【讨论】:

  • 通过将值设置为 2 来强制执行暗模式不起作用:[UIInterfaceStyle] '2' is not a recognized value for UIUserInterfaceStyle. Defaulting to Light.
  • 在 plist 中有这个键会导致 App Store 被拒绝。
  • AppStore 不再拒绝 plist.info 中的这个属性。因为我们的应用程序已经是黑暗的,所以我输入了“Dark”(大写)。没问题。这可以让我们正确使用系统控件。
  • 是的,我做到了。这并没有改变 Apple 确实在 plist 中接受此参数的事实,这正是我试图阐明的。
  • 我尝试设置“LIGHT”、“Light”、“light”、“.light”、“1”——都是一样的——它不起作用。 Xcode:版本 11.3.1 (11C504)
【解决方案7】:

如果您想退出整个应用程序,上述答案有效。如果您正在使用具有 UI 的库,并且您没有编辑 .plist 的奢侈,您也可以通过代码来完成。

如果您是针对 iOS 13 SDK 进行编译,您可以简单地使用以下代码:

斯威夫特:

if #available(iOS 13.0, *) {
    self.overrideUserInterfaceStyle = .light
}

对象-C:

if (@available(iOS 13.0, *)) {
    self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
}

但是,如果您希望代码也能针对 iOS 12 SDK 进行编译(目前仍然是最新的稳定 SDK),您应该使用选择器。带选择器的代码:

Swift(XCode 将对此代码显示警告,但这是目前唯一的方法,因为 SDK 12 中不存在属性,因此无法编译):

if #available(iOS 13.0, *) {
    if self.responds(to: Selector("overrideUserInterfaceStyle")) {
        self.setValue(UIUserInterfaceStyle.light.rawValue, forKey: "overrideUserInterfaceStyle")
    }
}

对象-C:

if (@available(iOS 13.0, *)) {
    if ([self respondsToSelector:NSSelectorFromString(@"overrideUserInterfaceStyle")]) {
        [self setValue:@(UIUserInterfaceStyleLight) forKey:@"overrideUserInterfaceStyle"];
    }
}

【讨论】:

  • 指定overrideUserInterfaceStyle所属的属性会更好。
【解决方案8】:

对于整个 App:(在info.plist 文件中):

<key>UIUserInterfaceStyle</key>
<string>Light</string>


窗口(通常是整个应用程序):

window!.overrideUserInterfaceStyle = .light

你可以从SceneDelegate获取窗口


UIViewController:

viewController.overrideUserInterfaceStyle = .light

你可以设置任何viewController,甚至在viewController里面self


UI 视图:

view.overrideUserInterfaceStyle = .light

您可以设置任何view,甚至在它的视图内self

如果您支持早期的 iO​​S 版本,您可能需要使用 if #available(iOS 13.0, *) { ,,, }


SwiftUI 视图:

.preferredColorScheme(.light) <- This Modifier

.environment(\.colorScheme, .light) <- This Modifier

【讨论】:

    【解决方案9】:

    您可以在 Xcode 11 的整个应用程序中关闭 暗模式

    1. 转到 Info.plist
    2. 像下面这样添加

      <key>UIUserInterfaceStyle</key>
      <string>Light</string>
      

    Info.plist 将如下所示...

    【讨论】:

    • 由于某种原因不适用于 Xcode 版本 11.3.1 (11C504)
    【解决方案10】:

    最新更新-

    如果您使用的是 Xcode 10.x,那么对于 iOS 13.x,默认的 UIUserInterfaceStylelight。在 iOS 13 设备上运行时,它将仅在 Light Mode 下工作。

    不需要在 Info.plist 文件中显式添加 UIUserInterfaceStyle 键,添加它会在您验证应用时出错,说:

    Info.plist 键无效。 Payload/AppName.appInfo.plist 文件中的“UIUserInterfaceStyle”键无效。

    使用 Xcode 11.x 时,仅在 Info.plist 文件中添加 UIUserInterfaceStyle 键。

    【讨论】:

    • 这与 Xcode 10 或 11 无关。如果用户从 Xcode 10 部署应用程序并且不处理暗模式,则该应用程序安装在 iPhone 11、Pro 或 Pro Max 中时会有暗模式问题。您需要更新到 Xcode 11 并解决此问题。
    • @NiranjanMolkeri 这与较新的 iPhone 无关。这与 iOS 13 上的暗模式有关。在以前的 iOS 13 测试版应用程序 UI 中,如果未明确处理,则会出现暗模式问题。但在最新版本中,这是固定的。如果您使用的是 XCode 10,则默认 UIUserInterfaceStyle 对于 iOS13 来说是浅色的。如果您使用的是 Xode11,则需要处理它。
    • 如果您使用 Xcode 10.3 将应用程序上传到 TestFligth 并且 plist 包含密钥 UIUserInterfaceStyle,您将遇到问题。它会说这是一个无效的 plist 文件。如果在 Xcode 10 中构建,您必须删除它,或者使用 Xcode 11 上传
    【解决方案11】:

    iOS 14.3 和 Xcode 12.3 更新

    在 info.plist 文件中添加 Appearance 作为 Light

    <key>Appearance</key>
    <string>Light</string>
    

    【讨论】:

    • @Yodagama 请检查您的模拟器 iOS 版本和 Xcode 版本。它应该可以正常工作,我刚刚在我的模拟器中对其进行了测试。
    • 它在 Xcode 12.3 和 iOS 14.3 中运行良好。对于您的版本,请尝试以下 UIUserInterfaceStyleLight
    【解决方案12】:

    如果您将 UIUserInterfaceStyle 键添加到 plist 文件中,Apple 可能会拒绝发布版本,如此处所述:https://stackoverflow.com/a/56546554/7524146 无论如何,明确告诉每个 ViewController self.overrideUserInterfaceStyle = .light 很烦人。但是您可以为您的根 window 对象使用这种代码和平:

    if #available(iOS 13.0, *) {
        if window.responds(to: Selector(("overrideUserInterfaceStyle"))) {
            window.setValue(UIUserInterfaceStyle.light.rawValue, forKey: "overrideUserInterfaceStyle")
        }
    }
    

    请注意,您不能在 application(application: didFinishLaunchingWithOptions:) 内执行此操作,因为此选择器在早期阶段不会响应 true。但你可以稍后再做。如果您在应用中使用自定义 AppPresenterAppRouter 类而不是在 AppDelegate 中自动启动 UI,这将非常容易。

    【讨论】:

      【解决方案13】:

      除其他回复外,根据我对以下内容的理解,在针对iOS 13 SDK(使用XCode 11)进行编译时,您只需要准备暗模式即可。

      系统假定应用链接到 iOS 13 或更高版本的 SDK 支持浅色和深色外观。在 iOS 中,您指定 通过分配特定的界面样式来获得您想要的特定外观 到您的窗口、视图或视图控制器。您还可以禁用支持 完全使用 Info.plist 键的暗模式。

      Link

      【讨论】:

        【解决方案14】:

        斯威夫特 5

        从暗模式切换到亮模式的两种方法:

        1- info.plist

            <key>UIUserInterfaceStyle</key>
            <string>Light</string>
        
        

        2- 以编程方式或运行时

          @IBAction private func switchToDark(_ sender: UIButton){
                UIApplication.shared.windows.forEach { window in
                    //here you can switch between the dark and light
                    window.overrideUserInterfaceStyle = .dark
                }
            }
        

        【讨论】:

          【解决方案15】:

          在 Xcode 12 中,您可以将添加更改为“外观”。这会奏效!!

          【讨论】:

            【解决方案16】:

            我的应用目前不支持深色模式,而是使用浅色应用栏颜色。通过将以下键添加到我的Info.plist,我能够将状态栏内容强制为深色文本和图标:

            <key>UIStatusBarStyle</key>
            <string>UIStatusBarStyleDarkContent</string>
            <key>UIUserInterfaceStyle</key>
            <string>Light</string>
            <key>UIViewControllerBasedStatusBarAppearance</key>
            <true/>
            

            在此处查找其他可能的值:https://developer.apple.com/documentation/uikit/uistatusbarstyle

            Flutter 用户

            不要忘记在 Flutter 应用栏上设置应用栏亮度属性,如下所示:

            AppBar(
                backgroundColor: Colors.grey[100],
                brightness: Brightness.light, // <---------
                title: const Text('Hi there'),
            ),
            

            【讨论】:

              【解决方案17】:

              是的,您可以通过在 viewDidLoad 中添加以下代码来跳过:

              if #available(iOS 13.0, *) {
                      // Always adopt a light interface style.
                      overrideUserInterfaceStyle = .light
                  }
              

              【讨论】:

                【解决方案18】:

                Objective-c 版本

                 if (@available(iOS 13.0, *)) {
                        _window.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
                    }
                

                【讨论】:

                  【解决方案19】:

                  将此添加到info.plist

                  <key>UIUserInterfaceStyle</key>
                      <string>Light</string>
                  

                  【讨论】:

                    【解决方案20】:
                     if #available(iOS 13.0, *) {
                                overrideUserInterfaceStyle = .light
                            } else {
                                // Fallback on earlier versions
                            }
                    

                    【讨论】:

                    • 你能解释一下这个答案将如何解决问题,而不是发布纯代码答案。
                    • 是的,当然@ArunVinoth 在 IOS 13 中引入了暗模式,因此如果您的部署目标低于 13,请使用上述代码,否则您可以使用 if 块中编写的简单语句。
                    【解决方案21】:

                    是的..您可以在 iOS 项目中添加以下设置。

                    在 info.plist 文件中将 UIUserInterfaceStyle 添加到 Light。

                    如果您的项目在 IONIC.. 您可以在配置文件中添加以下设置

                    <platform name="ios">
                      <edit-config file="*-Info.plist" mode="merge" target="UIUserInterfaceStyle">
                      <string>Light</string>
                     </edit-config>
                    </platform>
                    

                    使用这些设置,设备暗模式不会影响您的应用。

                    【讨论】:

                      【解决方案22】:

                      这里有一些提示和技巧,您可以在应用中使用它们来支持或绕过暗模式。

                      第一个技巧:覆盖 ViewController 样式

                      你可以通过

                      覆盖UIViewController的界面风格

                      1: overrideUserInterfaceStyle = .dark //适用于深色模式

                      2: overrideUserInterfaceStyle = .light //用于灯光模式

                      class ViewController: UIViewController {
                          override func viewDidLoad() {
                              super.viewDidLoad()
                              overrideUserInterfaceStyle = .light    
                          }
                      }
                      

                      第二个技巧:在 info.plist 中添加一个键

                      只需添加一个新密钥

                      UIUserInterfaceStyle

                      在您的应用 info.plist 中并将其值设置为 Light 或 Dark。这会将应用默认样式覆盖为您提供的值。 您不必在每个 viewController 中添加 overrideUserInterfaceStyle = .light 这一行,只需在 info.plist 中添加一行即可。

                      【讨论】:

                        【解决方案23】:

                        只需在您的 info.plist 文件中添加以下密钥:

                        <key>UIUserInterfaceStyle</key>
                            <string>Light</string>
                        

                        【讨论】:

                          【解决方案24】:

                          只需在 info.plist 文件中添加这些行:

                          <key>UIUserInterfaceStyle</key>
                          <string>light</string>
                          

                          这将强制应用仅在光照模式下运行。

                          【讨论】:

                          • 这已经被评论和回答了很多次了。即使是公认的答案也暗示了这一点。因此,此评论不会添加任何新信息。
                          【解决方案25】:

                          在 ViewController.swift 文件中添加 overrideUserInterfaceStyle = .light 或在 info.plist 文件中将外观更改为“light”

                          【讨论】:

                            【解决方案26】:

                            我会使用此解决方案,因为窗口属性可能会在应用程序生命周期中更改。因此需要重复分配“overrideUserInterfaceStyle = .light”。 UIWindow.appearance() 使我们能够设置将用于新创建的 UIWindow 对象的默认值。

                            import UIKit
                            
                            @UIApplicationMain
                            class AppDelegate: UIResponder, UIApplicationDelegate {
                            
                                var window: UIWindow?
                            
                                func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
                            
                                  if #available(iOS 13.0, *) {
                                      UIWindow.appearance().overrideUserInterfaceStyle = .light
                                  }
                            
                                  return true
                                }
                            }
                            

                            【讨论】:

                              【解决方案27】:
                              import UIKit
                              
                              extension UIViewController {
                              
                                  override open func awakeFromNib() {
                              
                                      super.awakeFromNib()
                              
                                      if #available(iOS 13.0, *) {
                              
                                          overrideUserInterfaceStyle = .light
                              
                                      }
                              
                                  }
                              }
                              

                              【讨论】:

                              • 请在您的答案中添加一些解释,以便其他人学习
                              【解决方案28】:

                              您可以这样做:将这个新键 UIUserInterfaceStyle 添加到 Info.plist 并将其值设置为 Light。并检查警报控制器是否以灯光模式显示。

                              UIUserInterfaceStyle 光 如果您在整个应用程序中强制使用亮/暗模式,而不管用户的设置如何,请通过将键 UIUserInterfaceStyle 添加到您的 Info.plist 文件并将其值设置为亮或暗。

                              【讨论】:

                                【解决方案29】:

                                这个问题有很多答案,而不是在info.plist 中使用它,您可以在AppDelegate 中设置它,如下所示:

                                #if compiler(>=5.1)
                                        if #available(iOS 13.0, *) {
                                            self.window?.overrideUserInterfaceStyle = .light
                                        }
                                        #endif
                                

                                在 Xcode 11.3、iOS 13.3 上测试

                                【讨论】:

                                  【解决方案30】:

                                  你可以在你的 plist 中设置这个

                                  或者您可以在资源部分中为浅色和深色主题设置相似的颜色,或者为此类任何主题选择单一颜色的“任何外观”。

                                  【讨论】:

                                  • 这与at least one previous answer 的答案几乎相同(可能更多)。请在提供新答案之前查看答案。不要提交新的答案,除非你有一些实质性的东西要添加到之前没有说过的对话中。
                                  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
                                  猜你喜欢
                                  • 2021-12-02
                                  • 2020-07-04
                                  • 2020-02-04
                                  • 2020-01-18
                                  • 2020-02-26
                                  • 2021-04-05
                                  • 2020-02-11
                                  • 2019-11-15
                                  • 2019-12-03
                                  相关资源
                                  最近更新 更多