How do you combine multiple state variables to form another?
I want to change the value of height OR width by some user interaction, and have everything in the view update accordingly. So the height OR width would change, and the area would change.
I imagine it would look something like this
@State var width: CGFloat = 50.0
@State var height: CGFloat = 100.0
@State var area: CGFloat // somehow equal to width*height
current solution is just calling a func
func area() -> CGFloat {
width * height
}
Don't make area
@State
; just make it a computed variable:
@State var height: CGFloat = 50.0
@State var width: CGFloat = 100.0
var area: CGFloat {
width * height
}
var body: some View {
VStack {
Text("Width: \(width)")
Text("Height: \(height)")
Text("Area \(area)")
Button(action: {
self.height *= 2
}) {
Text("Double height")
}
Button(action: {
self.width += 10
}) {
Text("Add 10 to width")
}
}
}
I added some code to illustrate that if width
or height
changes, area
will change too, because width
or height
changing cause the view to be redrawn since they are @State
. Since area
is computed, when the view is redrawn, area
is determined to be the product of the updated width
and height
values. Doing it as a function like you said in your current solution should also work, though.
If you want area
to be @State
so that you can pass it to other views as a Binding
, do this:
struct ContentView: View {
@State var height: CGFloat = 50.0
@State var width: CGFloat = 100.0
var area: Binding<CGFloat> {
Binding(get: {
self.height * self.width
}) { (newVal) in
}
}
var body: some View {
VStack {
Text("Width: \(width)")
Text("Height: \(height)")
Text("Area \(area.wrappedValue)")
BindingView(num: area)
BindingView(num: $height)
Button(action: {
self.height *= 2
}) {
Text("Double height")
}
Button(action: {
self.width += 10
}) {
Text("Add 10 to width")
}
}
}
struct BindingView: View {
@Binding var num: CGFloat
var body: some View {
Text("Binding number: \(num)")
}
}
I created BindingView
as an example of how to use bindings in different ways. For @State
variables, you effectively turn them into a Binding
by adding the $
prefix, but since area is explicitly Binding
, you do not need the $
. Also to access the value inside the Binding
, you just do the variable .wrappedValue
.
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