This conduct has been mounted. As of Xcode 12.0 (the iOS 14.0/macOS 11.0 SDKs), sheets do inherit their atmosphere.
In contrast to different views, modal sheets in SwiftUI do not inherit the atmosphere from their mother or father.
The atmosphere is SwiftUI’s approach to go knowledge implicitly to youngster views. Amongst different issues, the atmosphere accommodates app- or system-wide preferences, such because the person’s locale or the present colour scheme. Basically, you’ll be able to consider the atmosphere as a big, heterogeneous dictionary that will get handed implicitly to each view.
Many built-in SwiftUI views take the atmosphere into consideration once they draw themselves. We are able to make the most of this to override a setting for all youngster views with a single line of code. Contemplate this instance:
VStack(spacing: 8) {
Textual content("Line 1")
HStack {
Textual content("Line 2")
VStack {
Textual content("Line 2a")
Textual content("Line 2b")
}
}.font(.title)
Textual content("Line 3")
}
The .font(.title)
modifier on the HStack
mutates the corresponding worth within the present atmosphere, which then will get handed to the stack’s youngster views. And since Textual content
grabs its font from the atmosphere, all textual content views on this part of the view tree are rendered with a bigger font dimension. Be aware that the modified atmosphere additionally applies to oblique kids of the HStack
.
The next instance creates a root view whose locale and dynamic kind dimension have been overridden within the atmosphere. The view shows a formatted date and the present dynamic kind dimension setting. Right here’s the code for the foundation view:
struct RootView: View {
var physique: some View {
RootViewContent()
.atmosphere(.sizeCategory, .accessibilityMedium)
.atmosphere(.locale, Locale(identifier: "ja_JP"))
}
}
struct RootViewContent: View {
@State var isPresentingSheet = false
@Surroundings(.sizeCategory) var sizeCategory
var physique: some View {
VStack(spacing: 16) {
Textual content("Root View").font(.title)
Textual content("(Date(), formatter: dateFormatter)")
Textual content("Measurement class: (String(describing: sizeCategory))")
Button("Open Sheet") {
self.isPresentingSheet = true
}
}
.sheet(isPresented: self.$isPresentingSheet) {
ChildView()
}
}
}
Tapping the button within the root view units a state variable that triggers the presentation of a modal sheet, utilizing the .sheet
modifier:
// …
.sheet(isPresented: self.$isPresentingSheet) {
ChildView()
}
// …
The view that will get introduced shows the identical knowledge as the foundation view, with out modifying the atmosphere in any method:
struct ChildView: View {
@Surroundings(.sizeCategory) var sizeCategory
var physique: some View {
VStack(spacing: 16) {
Textual content("Little one View").font(.title)
Textual content("(Date(), formatter: dateFormatter)")
Textual content("Measurement class: (String(describing: sizeCategory))")
}
}
}
I’d count on that the introduced view inherits the atmosphere from the presenting view (some modifications however because the presentation mode can also be saved within the atmosphere), however that’s clearly not the case; whereas the foundation view accurately makes use of the Japanese locale and a really giant dynamic kind setting, the kid view goes again to the system locale and textual content dimension:
I’m undecided if that is intentional or a bug. (Replace: It’s a bug.) I suppose should you see sheets as unbiased entities that shouldn’t be affected by their presenting view, it is smart for some atmosphere values to not get propagated. Examples of this sort would possibly embrace:
For different settings, similar to locale and dynamic kind dimension, not propagating appears the fallacious option to me. It seems to be like there is no such thing as a single possibility that works for all the pieces, although. And making this a configurable conduct that each EnvironmentKey
can determine for itself is also complicated.
If you wish to propagate an atmosphere worth to a sheet, it’s essential to achieve this manually. In our instance, the code would appear to be this:
// …
.sheet(isPresented: self.$isPresentingSheet) {
ChildView()
.atmosphere(.sizeCategory, self.sizeCategory)
.atmosphere(.locale, self.locale)
}
// …
(This assumes that you just additionally added a property @Surroundings(.locale) var locale
to the foundation view with a purpose to entry the present locale contained in the atmosphere.)