iOS 14 Widget Detect System Theme Change
Although Widget views are static, you may still detect @Environment(\.colorScheme)
.
Here is a simple demo:
struct WidgetEntryView: View {
@Environment(\.colorScheme) var colorScheme
var entry: Provider.Entry
var bgColor: some View {
colorScheme == .dark ? Color.red : Color.orange
}
var body: some View {
ZStack {
bgColor
Text(entry.date, style: .time)
}
}
}
Note that when the system color scheme changes:
- only your View is redrawn, the
getTimeline
function is not called again - the default colors change automatically when the system color scheme changes
Here is a GitHub repository with different Widget examples including the Environment Widget.
Update Widget when appearance changes
- Create two screenshots (one per theme) and pass it in the entry:
struct SimpleEntry: TimelineEntry {
let date: Date
let mapScreenshots: [ColorScheme: Image]
}
struct Provider: TimelineProvider {
...
func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> Void) {
let entry = SimpleEntry(
date: Date(),
mapScreenshots: [
// replace with actual map screenshots
.dark: Image(systemName: "plus"),
.light: Image(systemName: "minus"),
]
)
let timeline = Timeline(entries: [entry], policy: .never)
completion(timeline)
}
}
- Use
@Environment(\.colorScheme)
to react to theme changes:
struct WidgetEntryView: View {
@Environment(\.colorScheme) var colorScheme
var entry: Provider.Entry
var body: some View {
if let screenshot = entry.mapScreenshots[colorScheme] {
screenshot
}
}
}
- iOS 14 Widget Detect System Theme Change
Disable Light Mode in Widget Extension iOS 14
Add the desired color to the widget’s asset catalog, then set the NSWidgetBackgroundColorName in your widget’s build settings.
Docs:
https://developer.apple.com/documentation/bundleresources/information_property_list/nswidgetbackgroundcolorname
Changing iOS App theme automatically between light and dark depending on iOS environmental theme
After banging my head against a brick wall for a few hours, finally figured it out (For anyone else having a similar issue).
The trick is that yes, you do in fact need to place the code that selects the theme inside the line
return CupertinoApp( <Here> )
You can do this through:
builder: (BuildContext context, Widget child) {
final Brightness brightnessValue = MediaQuery.of(context).platformBrightness;
bool isDark = brightnessValue == Brightness.dark;
// All your code to set your two themes, light and dark can go here.
}
In this way, instead of the chicken&egg scenario I was imagining, you are setting the theme state at the moment you need it.
Hope this helps someone.
How to check if dark mode is enabled on iOS/Android using Flutter?
There are two ways:
NO
context
required. Can be used ininitState
for example:var brightness = SchedulerBinding.instance.window.platformBrightness;
bool isDarkMode = brightness == Brightness.dark;or (as suggested by Moore's Lawyer)
var brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness;
bool isDarkMode = brightness == Brightness.dark;context
is required:var brightness = MediaQuery.of(context).platformBrightness;
bool isDarkMode = brightness == Brightness.dark;
iOS 14 Widget auto-refresh every day
Actually, it seems to be I overlooked it, the widget actually refreshes, it was me, who didn't refresh the data itself. (I'm using UserDefaults to share data between my app and the widget, and even though the widget refreshed properly, as the data in UserDefaults was not updated, the same was shown over and over again.)
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
Related Topics
How to Get Data to Return from Nsurlsessiondatatask in Swift
Display Array in a Label in Swift
Saving a Screen Recording with Rpscreenrecorder Start Capture
Auto Height Does Not Work in UIview in Swift 3
How to Count Number of Sprites Swift
How to Stop Dispatchgroup or Operationqueue Waiting
Alamofire Nonblocking Connection
Using UIscrollview Correctly in Swiftui
Swift 4, Simultaneous Access to Tuple Members as Inout
Navigationview Inside a Tabview Swift UI
Uiscrollview Controller Not Scrolling Fully
Retrieve Data from an Unknown Child Name with Firebase and Swift
Unexpectedly Found Nil While Unwrapping an Optional Value with Avaudioplayer
How to Update User Interface on Core Data
Get Out of Navigation Controller and Go Back to Tab Bar View