是否可以在 iOS 13 上选择退出暗模式?

Posted

技术标签:

【中文标题】是否可以在 iOS 13 上选择退出暗模式?【英文标题】:Is it possible to opt-out of dark mode on 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 会接受。 【参考方案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 的解决方案,请参阅 ***.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 List 和 UIUserInterfaceStyle - 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 的整个应用程序中关闭 暗模式

    转到 Info.plist

    像下面这样添加

    <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://***.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。

以上是关于是否可以在 iOS 13 上选择退出暗模式?的主要内容,如果未能解决你的问题,请参考以下文章

如果用户在其设备上选择了省电位置模式,是不是可以在 Android 上获得高精度的位置更新?

如何为 wkwebview 使用 iOS 13 暗模式

iOS 13 中的暗模式启动屏幕

在群聊应用程序上选择猫鼬模式?

如何防止 iOS 13 暗模式破坏电子邮件

iOS 13 暗模式 objc 字符串