SwiftUI - How do I check to see if dark mode is enabled?

后端 未结 4 512
太阳男子
太阳男子 2020-12-22 05:36

How do I check to see if dark mode on the device is enabled. I want to check this from within a view and conditionally show or hide a shadow.

I thought I could jus g

相关标签:
4条回答
  • 2020-12-22 05:47

    You are using colorScheme correctly. But it looks like you have a different issue - placing a modifier inside an if statement. I found that, unlike a View, modifiers don't work that way.

    The answer is to create a custom ViewModifier. In your case I'd package everything up into one modifier like this:

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

    And to use it:

    Circle()..modifier(CircleStyle())
    

    If you need to add more variables from your model, simply pass it into your modifier.

    0 讨论(0)
  • 2020-12-22 06:02

    In my code, I have a simple View extension, that makes the code a lot more readable. With it, I can apply modifiers conditionally:

    .conditionalModifier(self.colorScheme == .light, LightShadow())
    

    The full implementation is below:

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

    If you ever have a case where you want to apply different modifiers for true and false, here's another extension:

    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)
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-22 06:03

    Thanks to @dfd for pointing out that I can't use an if statement with a modifier. I updated my code like this for now. This just returns different versions of the circle in light and dark mode.

    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)
    }
    
    0 讨论(0)
  • 2020-12-22 06:04

    SwiftUI

    With the \.colorScheme key of an Environment variable:

    struct ContentView: View {
        @Environment(\.colorScheme) var colorScheme
    
        var body: some View {
            Text(colorScheme == .dark ? "In dark mode" : "In light mode")
        }
    }
    

    Also, it automatically updates on the change of the environment color scheme.


    UIKit

    To check the current, all object those conform to UITraitEnvironment protocol, including all UIView subclasses and all UIViewConttroller subclasses have access to the current style:

    myUIView.traitCollection.userInterfaceStyle == .dark
    myUIViewController.traitCollection.userInterfaceStyle == .dark
    

    To detect the change of the style, here is the full detailed answer

    0 讨论(0)
提交回复
热议问题