How can I check whether dark mode is enabled in iOS/iPadOS?

28,569

Solution 1

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 live changes of the style, here is the full detailed answer

Solution 2

For iOS 13, you can use this property to check if current style is dark mode or not:

if #available(iOS 13.0, *) {
    if UITraitCollection.current.userInterfaceStyle == .dark {
        print("Dark mode")
    }
    else {
        print("Light mode")
    }
}

Solution 3

You should check the userInterfaceStyle variable of UITraitCollection, same as on tvOS and macOS.

switch traitCollection.userInterfaceStyle {
case .light: //light mode
case .dark: //dark mode
case .unspecified: //the user interface style is not specified
}

You should use the traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) function of UIView/UIViewController to detect changes in the interface environment (including changes in the user interface style).

From Apple Developer Documentation:

The system calls this method when the iOS interface environment changes. Implement this method in view controllers and views, according to your app’s needs, to respond to such changes. For example, you might adjust the layout of the subviews of a view controller when an iPhone is rotated from portrait to landscape orientation. The default implementation of this method is empty.

System default UI elements (such as UITabBar or UISearchBar) automatically adapt to the new user interface style.

Solution 4

As mentioned by daveextreme, checking the current view user interface style doesn't always return the system style when you use the overrideUserInterfaceStyle property. In such cases it may be better to use the following code:

switch UIScreen.main.traitCollection.userInterfaceStyle {
case .light: //light mode
case .dark: //dark mode
case .unspecified: //the user interface style is not specified
}

Solution 5

in objective-c you'd want to do:

if( self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ){

        //is dark
}else{

    //is light

}
Share:
28,569
Tamás Sengel
Author by

Tamás Sengel

Updated on July 05, 2022

Comments

  • Tamás Sengel
    Tamás Sengel almost 2 years

    Starting from iOS/iPadOS 13, a dark user interface style is available, similar to the dark mode introduced in macOS Mojave. How can I check whether the user has enabled the system-wide dark mode?

  • Aaron Brager
    Aaron Brager about 5 years
    In addition to traitCollectionDidChange(_:), you can alternatively check for the change in UIView's layoutSubviews(), draw(_:), updateConstraints(), or tintColorDidChange(), or in UIViewController's updateViewConstraints(), viewWillLayoutSubviews(), or viewDidLayoutSubviews(). All of these methods are called every time the user interface style changes.
  • davextreme
    davextreme almost 5 years
    This will give you the current view's user interface style. If you've overriden it for that particular view, it won't tell you the system's style.
  • nontomatic
    nontomatic over 4 years
    Actually the last one (UIScreen...) was the only way to get the user's dark mode setting in the device's settings after overriding the userInterfaceStyle in my app. This way I was able to implement a "follow iOS dark mode" button which immediately updates the app's color theme even though I have custom themes and selection beside that. Unfortunately, reliably managing the status bar text color individually is impossible without overriding the userInterfaceStyle.
  • Ross Sullivan
    Ross Sullivan over 4 years
    This is great if you want to check in AppDelegate, since it does not have a traitCollection variable like UIViewController
  • Ranndom
    Ranndom over 4 years
    I ended up using it for Xamarin.Forms in my iOS project. By far the best answer out there. (good informed solid answer working better than the 100th copy by some blogger of the official doku at MS for Xamarin.) @Pedro Trujillo you saved my day. Thanks!
  • Chris
    Chris about 4 years
    Welcome to Stack Overflow. Code dumps without any explanation are rarely helpful. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please edit your question and explain how it works better than what the OP provided.
  • Lucas Chwe
    Lucas Chwe about 4 years
    @Chris. Thanks for the comment but literally every answer here is a code dump... The question is very straight forward and so is the answer. Thanks for your pointing that out tho, ill add more explanation
  • Chris
    Chris about 4 years
    That doesn't make code-only answers acceptable. This comment was flagged as either a "low quality answer", probably because it was purely code, or a "late response" (I can't remember which) and I commented via the review queue. It's always best to highlight what you changed, why you changed it, and how your answer improves upon any existing ones. I count ten answers that predate yours. Make yours stand out.
  • Leonid Silver
    Leonid Silver almost 4 years
    Note that may help somebody: if you have UIUserInterfaceStyle set to light in your info.plist, this methods will always return light
  • Valentin Shamardin
    Valentin Shamardin almost 4 years
    This doesn't react on disabled dark mode. If you use window?.overrideUserInterfaceStyle = .light then UITraitCollection.current.userInterfaceStyle can return .dark.
  • Dave Levy
    Dave Levy almost 4 years
    I used this method in my ContentView to change the accent color of a Tab Bar interface. At the end of the Tab View I used .accentColor(colorScheme == .dark ? .green : .black)
  • Yogendra Patel
    Yogendra Patel over 3 years
    This not work in my case. Make my iOS app to Mac supported. My mac mini current Appearance is Dark, in appdelegate file i sometime get light and sometime get dark mode, not getting every time dark mode. Please help me.
  • Ishmael7
    Ishmael7 over 3 years
    I get Type annotation missing in pattern when declaring @Enironement like that.
  • famfamfam
    famfamfam about 3 years
    any. ios 11 version?
  • Daniel Saidi
    Daniel Saidi almost 3 years
    For me, using a keyboard extension, UITraitCollection.current.userInterfaceStyle returns the correct value when the extension launches, but then never changes when I toggle light and dark mode on and off.
  • Kozmotronik
    Kozmotronik almost 3 years
    This answer is the best fit for checking the theme within a non UIViewController class.