I’m new to learning SwiftUI and XCode and am unable to figure out how to pass a variable from view to another. I read on @State and @Binding variables but from what I can tell that is for values that change. I have a static value that I calculate based on the date when the user opens the app.
The variable is the current moon phase and is stored locally in my main ContentView. I want to pass this variable to a second view that’s accessed by clicking a NavigationLink.
ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
let currentMoonPhaseArray = calculateMoonPhase()
let moonPhase = currentMoonPhaseArray[0]
NavigationView{
ScrollView(.vertical, showsIndicators:true) {
VStack(spacing:3){
NavigationLink(destination: MoonPhaseView()){
Text("Moon Phase - " + moonPhase)
}
}
}
.frame(maxWidth: .infinity)
.navigationTitle("MySky")
.navigationBarTitleDisplayMode(.inline)
}
}
}
MoonPhaseView.swift
import SwiftUI
struct MoonPhaseView: View {
var body: some View {
HStack{
Text("MoonPhaseView!")
}
}
}
struct MoonPhaseView_Previews: PreviewProvider {
static var previews: some View {
MoonPhaseView()
}
}
My goal is to have the calculated moon phase from ContentView.swift be passed to the MoonPhaseView.swift. I believe that bindings are the correct approach from what I’ve read, but all binding implementations seem to be for updating views often.
Thanks for any help or pointers!
2
Answers
You haven’t shown what the type of
moonPhase
is, so I’m just going to useString
as an example.Note that every time
MoonPhaseView
is used, you must provide aphase
parameter so that it has a value to fillvar phase : String
. You could provide a default value, but that doesn’t seem like it would do much good here.Not directly related to your question, but I might suggest that calculating the phase in the
body
might lead to undesirable results, especially if it’s an expensive calculation or it has to contact an API or something. You might want to consider doing this inonAppear
and keeping it in a@State
variable in yourContentView
, or perhaps even using anObservableObject
as a view model and storing the phase there.You can use "Environment" to pass system-wide settings to views and child views.
For example: