SwiftUI - Как проверить, включен ли темный режим?
Как проверить, включен ли темный режим на устройстве. Я хочу проверить это изнутри вида и условно показать или скрыть тень.
Я думал, что смогу просто получить цветовую схему из окружающей среды, но я думаю, что мне что-то не хватает.
struct FloatingAddButton : View {
@Environment(\.colorScheme) var colorScheme
@Binding var openAddModal: Bool
var body : some View {
VStack {
Spacer()
HStack() {
Spacer()
Button(action: {
self.openAddModal = true
}) {
ZStack {
Circle()
.foregroundColor(Color(RetroTheme.shared.appMainTint))
.frame(width: 50, height: 50, alignment: .center)
if(self.colorScheme == .light) {
.shadow(color: .secondary, radius: 5, x: 0, y: 0)
}
Image(systemName: "plus")
.foregroundColor(Color.white)
}
} // End Button
}
}
}
}
5 ответов
В моем коде есть простое расширение View, которое делает код более читаемым. С его помощью я могу условно применять модификаторы:
.conditionalModifier(self.colorScheme == .light, LightShadow())
Полная реализация приведена ниже:
extension View {
// If condition is met, apply modifier, otherwise, leave the view untouched
public func conditionalModifier<T>(_ condition: Bool, _ modifier: T) -> some View where T: ViewModifier {
Group {
if condition {
self.modifier(modifier)
} else {
self
}
}
}
}
struct FloatingAddButton : View {
@Environment(\.colorScheme) var colorScheme
@Binding var openAddModal: Bool
var body : some View {
VStack {
Spacer()
HStack() {
Spacer()
Button(action: { self.openAddModal = true }) {
ZStack {
Circle()
.foregroundColor(Color(.red))
.frame(width: 50, height: 50, alignment: .center)
.conditionalModifier(self.colorScheme == .light, LightShadow())
Image(systemName: "plus")
.foregroundColor(Color.white)
}
}
} // End Button
}
}
}
struct LightShadow: ViewModifier {
func body(content: Content) -> some View {
content.shadow(color: .secondary, radius: 5, x: 0, y: 0)
}
}
Если у вас когда-нибудь был случай, когда вы захотели применить разные модификаторы для true и false, вот еще одно расширение:
extension View {
// Apply trueModifier if condition is met, or falseModifier if not.
public func conditionalModifier<M1, M2>(_ condition: Bool, _ trueModifier: M1, _ falseModifier: M2) -> some View where M1: ViewModifier, M2: ViewModifier {
Group {
if condition {
self.modifier(trueModifier)
} else {
self.modifier(falseModifier)
}
}
}
}
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
Чтобы обнаружить изменение стиля, вот полный подробный ответ
Спасибо @dfd за указание на то, что я не могу использовать оператор if с модификатором. Я обновил свой код вот так. Это просто возвращает разные версии круга в светлом и темном режиме.
if colorScheme == .light {
Circle()
.foregroundColor(Color(RetroTheme.shared.appMainTint))
.frame(width: 50, height: 50, alignment: .center)
.shadow(color: .secondary, radius: 5, x: 0, y: 0)
} else {
Circle()
.foregroundColor(Color(RetroTheme.shared.appMainTint))
.frame(width: 50, height: 50, alignment: .center)
}
Вы которые с помощьюcolorScheme
правильно. Но похоже, что у вас другая проблема - размещение модификатора внутриif
заявление. Я обнаружил, что в отличие отView
, модификаторы не работают.
Ответ - создать собственный ViewModifier
. В вашем случае я бы упаковал все в один модификатор следующим образом:
struct CircleStyle: ViewModifier {
@Environment (\.colorScheme) var colorScheme:ColorScheme
func body(content: Content) -> some View {
if colorScheme == .light {
return content
.foregroundColor(Color(RetroTheme.shared.appMainTint))
.frame(width: 50, height: 50, alignment: .center)
.shadow(color: .secondary, radius: 5, x: 0, y: 0)
} else {
return content
.foregroundColor(Color(RetroTheme.shared.appMainTint))
.frame(width: 50, height: 50, alignment: .center)
}
}
И использовать это:
Circle()..modifier(CircleStyle())
Если вам нужно добавить больше переменных из вашей модели, просто передайте их в свой модификатор.
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 внутри тернарного оператора.
Отличный вариант использования для этого, если вы хотите поддерживать различные пользовательские интерфейсы, когда устройство пользователя находится в темном режиме.
Удачного кодирования;