从 iOS/iPadOS 13 开始,可以使用深色用户界面样式,类似于 macOS Mojave 中引入的深色模式。如何检查用户是否启用了系统范围的暗模式?
16 回答
对于iOS 13,您可以使用此属性检查当前样式是否为暗模式:
if #available(iOS 13.0, *) {
if UITraitCollection.current.userInterfaceStyle == .dark {
print("Dark mode")
}
else {
print("Light mode")
}
}
您应该检查 的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?)
功能来检测界面环境的变化(包括用户界面样式的变化)。UIView
UIViewController
来自Apple 开发者文档:
当 iOS 界面环境发生变化时,系统会调用该方法。根据您的应用程序的需要,在视图控制器和视图中实现此方法,以响应此类更改。例如,当 iPhone 从纵向旋转到横向时,您可能会调整视图控制器的子视图的布局。此方法的默认实现为空。
系统默认的 UI 元素(例如UITabBar
或UISearchBar
)会自动适应新的用户界面样式。
overrideUserInterfaceStyle
正如 daveextreme 所提到的,当您使用该属性时,检查当前视图用户界面样式并不总是返回系统样式。在这种情况下,最好使用以下代码:
switch UIScreen.main.traitCollection.userInterfaceStyle {
case .light: //light mode
case .dark: //dark mode
case .unspecified: //the user interface style is not specified
}
在objective-c中你想做:
if( self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ){
//is dark
}else{
//is light
}
对于斯威夫特:
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视频
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
要检测风格的实时变化,这里是完整的详细答案
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!
为 write 方法 1 次创建一个类函数并在任何你想要的地方使用
func isDarkMode() -> Bool{
if #available(iOS 12.0, *) {
if UIScreen.main.traitCollection.userInterfaceStyle == .dark {
return true
} else {
return false
}
} else {
return false
}
}
目标 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
}
}
下面的帮助方法适用于任何 iOS 版本:
var isDarkMode: Bool {
guard #available(iOS 12.0, *) else {
return false
}
return UIScreen.main.traitCollection.userInterfaceStyle == .dark
}
用法:
view.backgroundColor = isDarkMode ? .black : .white
检测变化的最佳点是 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
}
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
你可以使用这个扩展:
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
}
}
您可以使用以下代码检查项目中的亮模式或暗模式:
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
}
您可以使用此方法轻松检测暗模式或亮模式 Swift 5
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if traitCollection.userInterfaceStyle == .light {
print("Light mode")
} else {
print("Dark mode")
}}
也许一些不错的扩展?
public extension UIViewController {
@available(iOS 12.0, *)
public var isDarkMode: Bool { traitCollection.userInterfaceStyle == .dark }
}