I’m making a simple app to calculate quantities for my bread baking. I have multiple "Button"s to change the variables, however the Labels displaying those values aren’t refreshing when I press them.
Any button should trigger a refresh of almost all labels, because the math will change each one.
Example: Adding 50g of flour will affect the quantity of water, salt, and yeast. Changing a percentage of water would affect only the quantity of water needed.
Thanks,
Here’s my code:
import SwiftUI
var flourPercent = 100
var waterPercent = 70
var saltPercent = 6.0
var yeastPercent = 2.0
var flourQuantity = 1000
var waterQuantity = flourQuantity * waterPercent / 100
var saltQuantity = flourQuantity * Int(saltPercent) / 100
var yeastQuantity = flourQuantity * Int(yeastPercent) / 100
let yeastStr = String(format: "%.2f", ceil(yeastPercent*100)/100)
struct ContentView: View {
var body: some View {
HStack {
VStack {
Label("Subtract", systemImage: "")
Button(action: {
flourQuantity -= 50
print(flourQuantity)
}) {
Text("-")
}
Button(action: {
waterPercent -= 1
print(waterPercent)
}) {
Text("-")
}
Button(action: {
saltPercent -= 1
print(saltPercent)
}) {
Text("-")
}
Button(action: {
yeastPercent -= 0.1
print(yeastPercent)
}) {
Text("-")
}
}
VStack {
Label("Add", systemImage: "")
Button(action: {
flourQuantity += 50
print(flourQuantity)
}) {
Text("+")
}
Button(action: {
waterPercent += 1
print(waterPercent)
}) {
Text("+")
}
Button(action: {
saltPercent += 1
print(saltPercent)
}) {
Text("+")
}
Button(action: {
yeastPercent += 0.1
print(yeastPercent)
}) {
Text("+")
}
}
VStack {
Label("Baker's %", systemImage: "")
Label("(flourPercent)%", systemImage: "")
Label("(waterPercent)%", systemImage: "")
Label("(Int(saltPercent))%", systemImage: "")
Label(yeastStr + "%", systemImage: "")
}
VStack {
Label("Quantity", systemImage: "")
Label("(flourQuantity)g", systemImage: "")
Label("(waterQuantity)ml", systemImage: "")
Label("(saltQuantity)g", systemImage: "")
Label("(yeastQuantity)g", systemImage: "")
}
}
}
}
2
Answers
you can make this work with very few updates to your code. The properties you use to generate the text for your labels, have to be
@State
properties. This means whenever one of them is modified the view is redrawn:As you see I just prependes each variable that you change by the property wrapper @State. Read more about it here:
https://www.hackingwithswift.com/quick-start/swiftui/what-is-the-state-property-wrapper
You can use the
@State
property wrapper to track changes in real time to your variables. The changes will be reflected on-screen when the buttons are pressed:There are some slight changes to your code here.. note the location of the declaration of the @State variable. This is just a quick example to show how it works, you will need to tweak it to do what you want. I set the initial values in the onAppear tag near the bottom…
Updated answer
1 – Define an ObservableObject class
2 – Publish your variables in that class
3 – IMPORTANT – Add the variable of the Environment to your ContentView Class in the SceneDelegate:
Then this new example will work. I have also changed the calculations to change when it detects the FlourQty has changed..