How can I check whether dark mode is enabled in iOS/iPadOS?
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
How to check for Dark Mode in iOS?
UIKit has had UITraitCollection for a while now. Since iOS 9 you could use UITraitCollection to see whether the device supports 3D Touch (a sad conversation for another day)
In iOS 12, UITraitCollection got a new property: var userInterfaceStyle: UIUserInterfaceStyle
which supports three cases: light
, dark
, and unspecified
Since UIViewController inherits UITraitEnvironment, you have access to the ViewController's traitCollection
. This stores userInterfaceStyle
.
UITraitEnviroment also has some nifty protocol stubs that help your code interpret when state changes happen (so when a user switches from the Dark side to the Light side or visa versa). Here's a nice coding example for you:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if self.traitCollection.userInterfaceStyle == .dark {
// User Interface is Dark
} else {
// User Interface is Light
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
// Trait collection has already changed
}
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
// Trait collection will change. Use this one so you know what the state is changing to.
}
}
Detect if iOS13 Dark Mode is enabled from Flutter/Dart
Here's how you can set different colors for light and dark mode, the app will automatically switch if the phone is set to dark mode or light mode.
MaterialApp(
theme: ThemeData(
brightness: Brightness.light,
primaryColor: Colors.red,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
// additional settings go here
),
);
::Update::
You can also get the platform brightness (Brightness.light / Brightness.dark) using
WidgetsBinding.instance.window.platformBrightness
but you will have to use the WidgetsBindingObserver
mixin and override the method below
@override
void didChangePlatformBrightness() {
print(WidgetsBinding.instance.window.platformBrightness); // should print Brightness.light / Brightness.dark when you switch
super.didChangePlatformBrightness(); // make sure you call this
}
see https://api.flutter.dev/flutter/widgets/WidgetsBindingObserver-class.html on how to use the mixin.
How to detect Light\Dark mode change in iOS 13?
SwiftUI
With a simple environment variable on the \.colorScheme
key:
struct ContentView: View {
@Environment(\.colorScheme) var colorScheme
var body: some View {
Text(colorScheme == .dark ? "Its Dark" : "Its. not dark! (Light)")
}
}
UIKit
As it described in WWDC 2019 - Session 214 around 23:30.
As I expected, this function is getting called a lot including when colors changing. Along side with many other functions for ViewController
and presentationController
. But there is some especial function designed for that has a similar signature in all View
representers.
Take a look at this image from that session:
Gray: Calling but not good for my issue, Green: Designed for this
So I should call it and check it inside this function:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
dropShadowIfNeeded()
}
}
This will guarantee to be called just once per change.
if you are only looking for the initial state of the style, check out this answer here
Swift How can you reset the colors of all the subviews on a page?
You need to use dynamic colors in order to have them adapt automatically. Here
UITraitCollection.current.userInterfaceStyle == .light ? .black : .white
you check for the interface style right at that moment and set the color, but that code is not re-evaluated automatically when the trait environment changes.
Instead, you can use one of the system colors (like .background
or .label
), which will adapt to dark/light mode changes automatically. If you want to define your own, the easiest way would be using asset catalogs. When you add a color there, you can define how it looks in light and dark mode separately.
Why doesn't my iOS app disable dark mode?
Simply you can add a new key UIUserInterfaceStyle
in your app info.plist (Notes: Xcode 12 and above has renamed to Appearance
) and set its value to Light or Dark
. this will override the app default style to the value you provide.
so you don't need to bother about having it anywhere else
How to set dark mode for NSToolbar in macOS Catalyst app?
This can be done by adding an macOS plugin which has access to the whole AppKit API. Instructions can be found here:
How to Access the AppKit API from Mac Catalyst Apps
Then you can set the desired appearance there at runtime, for example:
NSApplication.shared.appearance = NSAppearance(named: .darkAqua)
How to support dark mode for a UIlabelTextColor in iOS 13.x?
You can define a Color Sets in your asset catalog with different variants for light and dark mode:
You can then use the color in Interface Builder or code with UIColor(named: "Color")
.
It will also adapt to appearance changes automatically.
Related Topics
Uitextview Starts at Bottom or Middle of the Text
How to Define the Size of a Collectionview on Rotate
How to Check Whether Dark Mode Is Enabled in iOS/Ipados
Why Does Uicollectionview Log an Error When the Cells Are Fullscreen
Using Custom Fonts in Interface Builder
Gcd VS Performselectorinbackground/Performselectoronmainthread
Creating Thumbnail for Video in iOS
Adding Click Event on Infowindow/Marker in Google Maps Sdk for Native iOS/Objective C
iOS Unable to Find Plugins, Android Fine
Avcapturevideopreviewlayer Orientation - Need Landscape
How to Know If Nsassert Is Disabled in Release Builds
Swiftui: Unwanted Split View on iPad
Service Workers and iOS/Safari
Issue with Auto Layout on iOS 8 (Code Works Perfectly on iOS 7)