SwiftUI-如何检查是否启用了暗模式?

时间:2019-09-15 11:16:57

标签: swiftui

如何检查设备上是否启用了暗模式。我想从视图中检查并有条件地显示或隐藏阴影。

我认为我可以从环境中获得colorScheme,但我想我缺少一些东西。

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
            }
        }
    }

}

4 个答案:

答案 0 :(得分:2)

在我的代码中,我有一个简单的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)
            }
        }
    }
}

答案 1 :(得分:1)

正在正确使用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())

如果您需要从模型中添加更多变量,只需将其传递到修改器中即可。

答案 2 :(得分:1)

感谢@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)
}

答案 3 :(得分:0)

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

要检测样式的变化,请here is the full detailed answer