Как я могу проверить, включен ли темный режим в iOS/iPadOS?
Начиная с iOS/iPadOS 13, доступен темный стиль пользовательского интерфейса, аналогичный темному режиму, представленному в macOS Mojave. Как я могу проверить, активировал ли пользователь общесистемный темный режим?
17 ответов
Вы должны проверить 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 поворачивается из книжной в альбомную ориентацию. Реализация по умолчанию этого метода пуста.
Элементы пользовательского интерфейса системы по умолчанию (например, UITabBar
или же UISearchBar
) автоматически адаптируется к новому стилю пользовательского интерфейса.
Для iOS 13 вы можете использовать это свойство, чтобы проверить, является ли текущий стиль темным режимом или нет:
if #available(iOS 13.0, *) {
if UITraitCollection.current.userInterfaceStyle == .dark {
print("Dark mode")
}
else {
print("Light mode")
}
}
Как упоминал daveextreme, проверка стиля пользовательского интерфейса текущего представления не всегда возвращает системный стиль, когда вы используете overrideUserInterfaceStyle
свойство. В таких случаях может быть лучше использовать следующий код:
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
}
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
Чтобы обнаружить живые изменения стиля, вот полный подробный ответ
Для Swift:
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.
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!
Создайте функцию класса для метода записи 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
Лучшая точка для обнаружения изменений - это функция traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) UIView/UIViewController.
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 может вызываться для других изменений свойств, таких как вращение устройства. Вы можете проверить, отличается ли текущий вид, используя этот новый метод:
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
Вы можете легко определить темный или светлый режим с помощью этого метода Swift 5.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if traitCollection.userInterfaceStyle == .light {
print("Light mode")
} else {
print("Dark mode")
}}
Вы можете использовать это расширение:
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
}
}
SwiftUI позволяет очень просто определить, включен ли темный режим. Нам просто нужно добавить переменную @Enviroment и использовать свойство .colorScheme для сканирования настроек на нашем устройстве и проверки того, включен ли темный режим.
Давайте посмотрим на код ниже.
struct ContentView: View {
@Environment(\.colorScheme) var colorScheme
var body: some View {
ZStack {
Color(colorScheme == .light ? .blue : .red)
Text("Hello, World!")
}
}
}
В приведенном выше коде мы создаем переменную @Environment, чтобы увидеть, находится ли наше устройство в темном режиме. Затем внутри нашего вида тела мы устанавливаем цвет фона на красный, если он в темном режиме, или на синий, если он не в темном режиме, используя нашу переменную colorScheme внутри тернарного оператора.
Отличный вариант использования для этого — если вы хотите поддерживать различные пользовательские интерфейсы, когда устройство пользователя находится в темном режиме.
Удачного кодирования;
Вы можете использовать следующий код для проверки светлого или темного режима в вашем проекте:
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
}
Как и в macOS, начиная с Mojave, вы можете определять изображения как для светлого, так и для темного режима в своем каталоге ресурсов, чтобы эти изображения использовались автоматически:
Может быть, какое-нибудь хорошее расширение?
public extension UIViewController {
@available(iOS 12.0, *)
public var isDarkMode: Bool { traitCollection.userInterfaceStyle == .dark }
}