65

从 iOS/iPadOS 13 开始,可以使用深色用户界面样式,类似于 macOS Mojave 中引入的深色模式。如何检查用户是否启用了系统范围的暗模式?

4

16 回答 16

62

对于iOS 13,您可以使用此属性检查当前样式是否为暗模式:

if #available(iOS 13.0, *) {
    if UITraitCollection.current.userInterfaceStyle == .dark {
        print("Dark mode")
    }
    else {
        print("Light mode")
    }
}
于 2019-09-26T16:20:08.360 回答
45

您应该检查 的userInterfaceStyle变量UITraitCollection,与 tvOS 和 macOS 上的相同。

switch traitCollection.userInterfaceStyle {
case .light: //light mode
case .dark: //dark mode
case .unspecified: //the user interface style is not specified
}

您应该使用/的traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)功能来检测界面环境的变化(包括用户界面样式的变化)。UIViewUIViewController

来自Apple 开发者文档

当 iOS 界面环境发生变化时,系统会调用该方法。根据您的应用程序的需要,在视图控制器和视图中实现此方法,以响应此类更改。例如,当 iPhone 从纵向旋转到横向时,您可能会调整视图控制器的子视图的布局。此方法的默认实现为空。

系统默认的 UI 元素(例如UITabBarUISearchBar)会自动适应新的用户界面样式。

于 2019-06-03T23:34:57.947 回答
28

overrideUserInterfaceStyle正如 daveextreme 所提到的,当您使用该属性时,检查当前视图用户界面样式并不总是返回系统样式。在这种情况下,最好使用以下代码:

switch UIScreen.main.traitCollection.userInterfaceStyle {
case .light: //light mode
case .dark: //dark mode
case .unspecified: //the user interface style is not specified
}
于 2019-09-12T13:47:14.983 回答
21

在objective-c中你想做:

if( self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ){

        //is dark
}else{

    //is light

}
于 2019-09-23T01:48:03.560 回答
15

对于斯威夫特:

if #available(iOS 12.0, *) {
  switch UIScreen.main.traitCollection.userInterfaceStyle {
    case .dark: // put your dark mode code here
    case .light: 
    case .unspecified: 
  }
}

对于目标 C:

if (@available(iOS 12.0, *)) {
        switch (UIScreen.mainScreen.traitCollection.userInterfaceStyle) {
            case UIUserInterfaceStyleDark:
                // put your dark mode code here
                break;
            case UIUserInterfaceStyleLight:
            case UIUserInterfaceStyleUnspecified:
                break;
            default:
                break;
        }
}

有关更多信息,请观看此 WWDC2019视频

于 2019-12-20T20:48:54.630 回答
13

SwiftUI

使用变量的\.colorScheme键:Environment

struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        Text(colorScheme == .dark ? "In dark mode" : "In light mode")
    }
}

此外,它会自动更新环境配色方案的变化。


UIKit

要检查当前,所有符合UITraitEnvironment协议的对象,包括所有UIView子类和所有UIViewConttroller子类都可以访问当前样式:

myUIView.traitCollection.userInterfaceStyle == .dark
myUIViewController.traitCollection.userInterfaceStyle == .dark

要检测风格的实时变化,这里是完整的详细答案

于 2020-09-04T06:55:05.353 回答
13

1/ 对于 UIView/UIViewController:

self.traitCollection.userInterfaceStyle == .dark

2/ 对于静态或其他:

UITraitCollection.current.userInterfaceStyle == .dark

但:

//Never use this! You will get wrong value in app extensions (ex. ToDay widget)
UIScreen.main.traitCollection.userInterfaceStyle == .dark //WRONG!
于 2019-10-05T12:01:36.250 回答
9

为 write 方法 1 次创建一个类函数并在任何你想要的地方使用

func isDarkMode() -> Bool{
    if #available(iOS 12.0, *) {
        if UIScreen.main.traitCollection.userInterfaceStyle == .dark {
            return true
        } else {
            return false
        }
    } else {
       return false
    }
}  
于 2019-11-12T06:54:01.920 回答
8

目标 C

要通过控制中心检测何时启用或禁用暗模式,请使用“appDidBecomeActive”通知,该通知将在您返回应用程序时触发。

//----------------------------------------------------------------------------
//                          viewWillAppear
//----------------------------------------------------------------------------
- (void)viewWillAppear {
    [super viewWillAppear];

    [[NSNotificationCenter defaultCenter]addObserver:self
                                   selector:@selector(appDidBecomeActive:)
                                   name:UIApplicationDidBecomeActiveNotification
                                   object:nil];

}

完成后不要忘记删除它:

//------------------------------------------------------------------------------------
//                    viewWillDisappear
//------------------------------------------------------------------------------------
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [[NSNotificationCenter defaultCenter] removeObserver:self        
                                 name:UIApplicationDidBecomeActiveNotification 
                                 object:nil];

}

当暗模式改变时,做你需要做的事情:

//----------------------------------------------------------------------------
//                          appDidBecomeActive
//----------------------------------------------------------------------------
-(void)appDidBecomeActive:(NSNotification*)note {
    if (@available(iOS 13.0, *)) {
        if( self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ){
            //dark mode
        }
        else {
            //not dark mode
        }
    }
    else {
        //fall back for older versions
    }
}
于 2019-11-05T10:21:38.417 回答
4

下面的帮助方法适用于任何 iOS 版本:

var isDarkMode: Bool {
    guard #available(iOS 12.0, *) else {
        return false
    }

    return UIScreen.main.traitCollection.userInterfaceStyle == .dark
}

用法:

view.backgroundColor = isDarkMode ? .black : .white
于 2020-05-13T23:55:05.670 回答
3

检测变化的最佳点是 UIView/UIViewController 的 traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) 函数。

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    let userInterfaceStyle = traitCollection.userInterfaceStyle // Either .unspecified, .light, or .dark
    // Update your user interface based on the appearance
}

通过覆盖视图控制器上的 traitCollectionDidChange 来检测外观变化是微不足道的。然后,只需访问视图控制器的 traitCollection.userInterfaceStyle。

但是,重要的是要记住,可能会调用 traitCollectionDidChange 来进行其他 trait 更改,例如设备旋转。您可以使用这种新方法检查当前外观是否不同:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    let hasUserInterfaceStyleChanged = previousTraitCollection.hasDifferentColorAppearance(comparedTo: traitCollection) // Bool
    // Update your user interface based on the appearance
}
于 2019-09-15T11:19:13.830 回答
2
var isDarkMode: Bool {
    guard #available(iOS 12.0, *) else {
        return false
    }
    let window = (UIApplication.shared.delegate as? AppDelegate)?.window
    return window?.traitCollection.userInterfaceStyle == .dark
}

如果您没有在 AppDelegate 中使用窗口,请从 SceneDelegate 调用窗口

它类似于上面的大多数答案,但是当我们使用

window?.overrideUserInterfaceStyle = .dark

可以称为

isDarkMode ? .black : .white
于 2020-11-18T14:29:36.207 回答
1

你可以使用这个扩展:

import UIKit

extension UIApplication {
    @available(iOS 13.0, *)
    var userInterfaceStyle: UIUserInterfaceStyle? {
        return self.keyWindow?.traitCollection.userInterfaceStyle
    }
}

@available(iOS 13.0, *)
    func setSystemTheme() {
        switch UIApplication.shared.userInterfaceStyle {
        case .dark?:
            currentTheme = .dark
        case .light?:
            currentTheme = .light
        default:
            break
        }
    }
于 2019-09-26T12:37:46.517 回答
0

您可以使用以下代码检查项目中的亮模式或暗模式:

func viewDidLoad() {
    super.viewDidLoad()

    switch traitCollection.userInterfaceStyle {
        case .light, .unspecified:
            // light mode detected
        case .dark:
            // dark mode detected
    }
}

您还可以检查界面样式的更改:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    let userInterfaceStyle = traitCollection.userInterfaceStyle // Either .unspecified, .light, or .dark
    // Update your user interface based on the appearance
}

就像自 Mojave 以来在 macOS 中一样,您可以在资产目录中为明暗模式定义图像,以便自动使用这些图像:

于 2020-10-19T06:38:35.330 回答
0

您可以使用此方法轻松检测暗模式或亮模式 Swift 5

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if traitCollection.userInterfaceStyle == .light {
    print("Light mode")
} else {
    print("Dark mode")
}}
于 2020-06-21T12:52:38.383 回答
0

也许一些不错的扩展?

public extension UIViewController {
    @available(iOS 12.0, *)
    public var isDarkMode: Bool { traitCollection.userInterfaceStyle == .dark }
}
于 2020-01-10T02:17:04.930 回答