I'm trying to pass one variable from one view to another in SwiftUI. I have a reset button in which I want to set the variable to zero in the other view.
I have tried creating a new struct in view one and accessing that variable in view 2.
// View 1
@State var count = MyNumber.number
// Body of app
Button(action: {self.count = self.count-10}) {
Text("-")
}
Text("\(count)")
struct MyNumber {
static var number = 0
}
// View 2
@State var countit = MyNumber.number
// Body
Button(action: {self.countit = 0}) {
Text("Reset")
}
Text in view one is still showing the number that was computed in View 1
The best solution here (to my opinion) is custom Bindings with a a wrapper View. That will give you two choices: Bind your (child) View with the parent View so that both parent and child can change the value. Don't bind child View with parent so that ONLY the child will save the value internally.
With @State, you tell SwiftUI that a view is now dependent on some state. If the state changes, so should the User Interface. It's a core principle of SwiftUI: data drives the UI.
'some' means opaque type. In SwiftUI, View is declared as a protocol @available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *) public protocol View { /// The type of view representing the body of this view.
If View2
is being used in View1
you could do something like this:
View1:
struct FirstView: View {
@State var count = 0
var body: some View {
VStack{
Text("\(self.count)")
Button(action:
{self.count = self.count-10})
{
Text("-")
}
SecondView(count: self.$count)
}
}
}
And View2:
struct SecondView: View {
@Binding var count: Int
var body: some View {
Button(action: {self.count = 0}) {
Text("Reset")
}
}
}
Edit
If they are completely different views and need single source of truth you could use an observableObject/EnvironmentVariables. The best way would be to add the environment variable to the ContentView
where it's first defined in the SceneDelegate
ContentView().environmentObject(SourceOfTruth())
Here is SourceOfTruth:
class SourceOfTruth: ObservableObject{
@Published var count = 0
}
Then you could use EnvironmentObjects to the other views:
Here is ContentView
:
struct ContentView: View {
@EnvironmentObject var truth: SourceOfTruth
var body: some View {
VStack {
FirstView()
SecondView()
}
}
}
Here is FirstView
:
struct FirstView: View {
@EnvironmentObject var truth: SourceOfTruth
var body: some View {
VStack{
Text("\(self.truth.count)")
Button(action:
{self.truth.count = self.truth.count-10})
{
Text("-")
}
}
}
}
Here is SecondView
:
struct SecondView: View {
@EnvironmentObject var truth: SourceOfTruth
var body: some View {
Button(action: {self.truth.count = 0}) {
Text("Reset")
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With