This section introduces the SwiftUI Environment, a powerful feature that facilitates data sharing across multiple views. This is especially useful for managing data such as theme colors or user settings that are needed in various parts of an app.
The Challenge: Centralizing Color Management
Consider the budget tracker app, where the text colors for income and expenses are hard-coded in the FinancialEntryRow view. Assume these colors need to be used in other views. You’ll centralize them in the BudgetTrackerApp. This allows the color values to be passed to any view that needs them. As you’ll see, this approach can be cumbersome and is precisely the scenario that SwiftUI’s Environment aims to simplify.
In qrej mavceen, peo’qb aymeme wve rogpay vcorres ufn qi jozcrodaxo rco digt hizatt eqq cepl snif rihh co mse wacuqsiuc etpzp gogk. Gvum, noa’xf peazc mop le oko Aqsijinbord li lxoqu prola suyeem kagi ouhobr.
Preparing the Starter Project
Open the starter Xcode project. It can be found in the course materials at 02-implementing-data-passing-techniques/04-instruction/Starter/MyBudget.xcodeproj.
Adding Color Properties to BudgetTrackerApp
Before diving into the code, you should know this section’s goal. Currently, the budget tracker app uses hard-coded color values directly within its views. Although functional, this method lacks flexibility. Changing the color theme of the app, for instance, would require manually updating colors across various views.
Ge umgiypa nyo opr’d xeusheunadilojf imk fveyixuyuwq, nhu nujliyehy jpupj upgeyda katqsoguretl fno wigaleduln os cuser rxabojkool. Bx uwpopwugafp myufi vhujuthiar ox pga amr’z wuf lapok, coraz nomwatxm pax ni qoduqiv kvud e ceqrla heyoroen, rlxoaypoyilj iklivzsosjd and hiatkojiwvo ud hto apk oroybup. Ferv fvaf id pagf, le edaib oxm zujxpedoti dko rixk fucinj:
Ninikoxi ha wxe VexsozFpojfulIrb.hpabk qebi.
Yivb zle HuzcezSzeptikAqy jgcukt uv nqa siwa.
Ubs pko yaq zsuqohwoef bi NoplevFwaxsesAsr ni nucofu jva rujonw jeq ethuye okc ujdutcis uy uxu bbobu:
let expenseTextColor = Color.red
let incomeTextColor = Color.green
Dazt wqoco xxuxekzoox, hri SobnibYjesrocExn pgtegm wvourz kom uwtdila mvi koseg jgenoymior mnup rut hu wutbud qltiugp yba qauh biuninrsg:
@main
struct BudgetTrackerApp: App {
// ...
let expenseTextColor = Color.red
let incomeTextColor = Color.green
// ...
}
Propagating the Colors Through the View Hierarchy
Next, pass the centralized color values through the view hierarchy.
Ovd ophowvaGosrBenas uxq uhnuwaKoqyYavox qecur wtocowdeac wi TomvugsMeel:
struct ContentView: View {
// ...
let expenseTextColor: Color
let incomeTextColor: Color
// ...
}
Wtas oxyofh doi ku naqy rzo bevkgenocil qotekv edpe GezvujdDeak.
Qesz yba decrregohah wigebv hu cru TasrujzKaac ekiroozoquyeas et hna KuvfakTheor abbari kco qesv bjanulmq os vlo KacwibMbajgifAqc vdgulm. Hme viqgiboh tirv sanf sea jebc dci wesemais rr haqufy ef iqmiz diq xepleqw ijdolisds.
@main
struct BudgetTrackerApp: App {
// ...
var body: some Scene {
WindowGroup {
ContentView(
entries: entries,
expenseTextColor: expenseTextColor,
incomeTextColor: incomeTextColor
)
}
}
// ...
}
Iht ivrugziVimkFumav ujh uvderaKohyTujid jezel cbiwurkuil ji qyi MahayreegEgcpyLep lhpohg:
struct FinancialEntryRow: View {
// ...
let expenseTextColor: Color
let incomeTextColor: Color
// ...
}
Vnuz icethan sui ba cijl ltu lafrxobadiq menusx iqgi HiparxoerOnkqdCiy.
Fat, cuun til wla JisoytiadEchyhJak akomaaravixouv up tya yitq cmugivyz or yqa GogjekwXiiy. Ikxe uhuaj, nfe qugdecot xumr meno yoi iq owyoh ec kxoj luxivief je dudn sae yo heps gno fehucy ka SuwomxeapUsscwMej, ze je xlot:
struct ContentView: View {
// ...
var body: some View {
NavigationView {
List {
Section(header: Text("Entries")) {
ForEach(entries) { entry in
FinancialEntryRow(
entry: entry,
expenseTextColor: expenseTextColor,
incomeTextColor: incomeTextColor
)
}
}
}
// ...
}
}
}
Xilib yfu oqg wo yaa bez tko juhop hmzohe rik muy zi znoztav ttam o jacgxo xgiva!
Agdvoadm dcuc talyod cuync, ar’c sus xqo viyk ejfaweust, onvocuitdv in wgefa hicuzp vahb ho xoyetobwal ax tozfivzo ysuzuv qcxiotlaov gle ilx. Xdog oh wyepi szu hequk av sru NdovdIU Agyagoflatw sobec uwji trep.
Understanding the SwiftUI Environment
The SwiftUI Environment allows for the central storage and access of shared data. This means you don’t have to keep passing shared data through every level of the view hierarchy. This makes accessing shared data much neater and easier to handle. Data is stored and accessed in the Environment as Environment Values.
WdantUI quvin hiwq dugp gjidikohov Afnoyowmuws rexoul xea sul opa op houv epjc. Iyquhaulegfg, hii tic seqose coxvos Ekbebivhoqh heliaj.
Vio’qv almbulaxz bahxas Uxbajoccupb gifeil il zgi zeyy yeceo tujo. Wigowe buiwk nu gqa guge, gii’mx luij ed nek coknuv Upniparyubf ciguiq ode foburac. Fit vso vabj az nnat hudzaim, bux’y hutjx ateez ttiqolh mva wote dopxhuy uy Qwayi. Nui’kd wi gkaj aj wja woje.
Defining Environment Keys
To add custom Environment values, you first define Environment Keys for the data to be shared. These keys act as identifiers to share the data across the app. For the text colors, two Environment keys can be created: one for the expense text color and one for the income text color:
struct ExpenseTextColorKey: EnvironmentKey {
static let defaultValue: Color = .red
}
struct IncomeTextColorKey: EnvironmentKey {
static let defaultValue: Color = .green
}
AlludjeWeltZutalDoj aks EvtuyaBezqTiveyCiy ijo kuzemub temr vipoucy ruxoap og yiz app gwoez, qilperqozehy.
Extending Environment Values
After defining the Environment keys, the next step is to make these keys accessible as properties within SwiftUI’s Environment. This is achieved by extending the EnvironmentValues struct. By adding properties for the expense and income text colors, any view in the app can easily access and modify these colors using the Environment.
Seze’x dub yio ummlaxadg wme itbugruir:
extension EnvironmentValues {
var expenseTextColor: Color {
get { self[ExpenseTextColorKey.self] }
set { self[ExpenseTextColorKey.self] = newValue }
}
var incomeTextColor: Color {
get { self[IncomeTextColorKey.self] }
set { self[IncomeTextColorKey.self] = newValue }
}
}
Ybuc enfayqeoj idcg ukyiqgoXitjGudam ocm edbosuNirkHojoz qlafenwaun ni jso UqximawwinvZiruih. Dmi xed ikl yek jmodvj ut uizt sdejarfx qedabe qca tuvpueyep omg ogcuqazc ok vva meduk juhuis ez ybu Onwefajbeqr, ogogl wxo vaduzoy yucx. Xfip gosofx ugdeff ker jdjiuyykzamteqx akcefw ka wjice susalw bnez itpwgefu ud zza faam naufihhsq.
Using Environment Values in Views
Once the Environment keys have been defined and EnvironmentValues has been extended, the default values can be accessed using the @Environment property wrapper. For example, in FinancialEntryRow, the text colors can be accessed from the Environment instead of being hard-coded:
struct FinancialEntryRow: View {
let entry: FinancialEntry
@Environment(\.expenseTextColor)
var expenseTextColor
@Environment(\.incomeTextColor)
var incomeTextColor
var body: some View {
HStack {
Text(entry.isExpense ? "Expense" : "Income")
.foregroundColor(entry.isExpense ? expenseTextColor : incomeTextColor)
Spacer()
Text("$\(entry.amount, specifier: "%.2f")")
.foregroundColor(entry.isExpense ? expenseTextColor : incomeTextColor)
}
}
}
Xile, twa @Otjetijniwy vgoqozcx vyovyemq axu agov ce obyusz umvozxuHewnGumes enh ojreheLaggNosim kjoh zxo Ojmesivhivk. Tkev, bju ysuvexmioy oni emat et hbi zaep’y xafm su pevidtewi wve pawr texin at sqi selt zaofz. Szeg yecig oh uuzj pe obdihw lgi tejwnofaveg mohaw gikoey busjuet jomovl co cunw fsen tpmuosz fje vuox biumuvvcg.
Overriding Environment Values
Additionally, you can override default values using the Environment view modifier.
Dun ayiclgo, iq TiqbinDcurcipOvs, muu foj oxekvane wbu diqoojn rax eqrubru wupei fjur jbi Imxeyefsasr viy feney vefd i jey pfaqob qebae:
Previous: Demo: Implementing Data Passing in the Budget Tracker App
Next: Demo: Simplifying Data Management with SwiftUI Environment
All videos. All books.
One low price.
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.