【问题标题】:SwiftUI - How do I check to see if dark mode is enabled?SwiftUI - 如何检查是否启用了暗模式?
【发布时间】:2020-01-16 12:12:02
【问题描述】:

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

我以为我可以从环境中获取 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
            }
        }
    }

}

【问题讨论】:

  • 正如 dfd 在下面指出的那样,问题是尝试使用带有修饰符的 if 语句。请参阅问题中的更新代码。
  • 两件事,我从来没有看到你的评论,因为你在评论上留下了“at”(@)符号。两年了,我也在学习!请参阅我对我的答案的评论,了解我希望你会做什么。在你和两个答案之间,这是 all 可以使用的东西。

标签: swiftui


【解决方案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())

如果您需要从模型中添加更多变量,只需将其传递给您的修饰符。

【讨论】:

  • 这对我不起作用。我收到一个错误Function declares an opaque return type, but the return statements in its body do not have matching underlying types。感谢您提供有关在修饰符上使用 if 语句的信息。有了它,我就可以让它工作了。
  • 首先,很高兴我能帮上忙。第二,好答案!太糟糕了,这是对您问题的编辑?请张贴您的答案!这没有什么问题,我很乐意支持它。 (你不能接受 - 我认为 - 但这个网站真的是关于两个 Q 和 A。如果可以的话?编辑问题标题以反映 真实 问题。这对每个人都有帮助!)
  • 会的,谢谢。我还是 Stack Overflow 的新手,所以我不知道所有的礼仪
  • @radicalappdev 你解决了那个错误吗?我也一样,谢谢
【解决方案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)
    }
}

如果您想对真假应用不同的修饰符,这里有另一个扩展:

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 对我们所有人来说都是新的。)与往常一样,至少对我来说,你比我们大多数 UIKit 编码人员都高出一个或更多的水平(我几乎不认为自己是其中之一)。真好!
  • 谢谢@dfd,一如既往的好。我已经编译了几个视图扩展,旨在使代码更具可读性。它在我的博客中,名为“查看扩展以获得更好的代码可读性”。干杯;-)
  • 我会定期查看您的博客,并且已经使用了一个作为圆角半径。没看到这个 - 但它让我通过你的使用钻入some
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    SwiftUI

    使用Environment 变量的\.colorScheme 键:

    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

    【讨论】:

      猜你喜欢
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 2021-10-07
      • 2020-03-04
      相关资源
      最近更新 更多