title: SwiftUI: How to let the user set the app appearance in real-time w/ options "light", "dark", and "system"?
body: <p>I am currently trying to implement a solution in an app where the user is supposed to be able to switch the app's appearance in real-time with the following options:</p>
  <ul>
  <li>System (applying whatever appearance is set in the iOS settings for the device)</li>
  <li>Light (applying .light color scheme)</li>
  <li>Dark (applying . dark color scheme)</li>
  </ul>
  <p>Setting light and dark color schemes has proven to be quite easy and responsive using .preferredColorScheme(); however, I have not yet found any satisfying solution for the &quot;System&quot; option.</p>
  <p>My current approach is the following:</p>
  <ol>
  <li>Getting the device color scheme using @Environment(.colorScheme) in ContentView</li>
  <li>Creating a custom view modifier for applying the respective color scheme on whatever view</li>
  <li>Using a modifier on &quot;MainView&quot; (that's where the real content of the app is supposed to live) to switch between the color schemes</li>
  </ol>
  <p>My idea was to embed MainView in ContentView so that the @Environment(.colorScheme) would not be disturbed by any colorScheme that is applied to MainView.</p>
  <p>However, it still doesn't work as supposed: When setting light and dark appearance, everything works as intended. However, when switching from light/dark to &quot;system&quot;, the change in appearance is only visible after re-launching the app. Expected behavior, however, would be that the appearance changes instantly.</p>
  <p>Any ideas on this?</p>
  <p>Here are the relevant code snippets:</p>
  <p><strong>Main view</strong></p>
  <pre><code>import SwiftUI
  
  struct MainView: View {
  
      @AppStorage(&quot;selectedAppearance&quot;) var selectedAppearance = 0
  
      var body: some View {
          VStack {
              Spacer()
              Button(action: {
                  selectedAppearance = 1
              }) {
                  Text(&quot;Light&quot;)
              }
              Spacer()
              Button(action: {
                  selectedAppearance = 2
              }) {
                  Text(&quot;Dark&quot;)
              }
              Spacer()
              Button(action: {
                  selectedAppearance = 0
              }) {
                  Text(&quot;System&quot;)
              }
              Spacer()
          }
      }
  }
  </code></pre>
  <p><strong>ContentView</strong></p>
  <pre><code>import SwiftUI
  
  struct ContentView: View {
  
      @Environment(\.colorScheme) var colorScheme
  
      var body: some View {
          MainView()
              .modifier(ColorSchemeModifier(colorScheme: colorScheme))
      }
  }
  </code></pre>
  <p><strong>&quot;Utilities&quot;</strong></p>
  <pre><code>import Foundation
  import SwiftUI
  
  struct ColorSchemeModifier: ViewModifier {
  
      @AppStorage(&quot;selectedAppearance&quot;) var selectedAppearance: Int = 0
      var colorScheme: ColorScheme
  
      func body(content: Content) -&gt; some View {
          if selectedAppearance == 2 {
              return content.preferredColorScheme(.dark)
          } else if selectedAppearance == 1 {
              return content.preferredColorScheme(.light)
          } else {
              return content.preferredColorScheme(colorScheme)
          }
      }
  }
  </code></pre>