New to SwiftUI.
I want to change the string calBudget in the UserSettings view and convert it to Int in the ContentView. the first problem is the Integer conversion is not working with my code. The second problem is, every keystroke in the UserSettings view is generating a new UserSettings view creating a bunch of nested views.
struct ContentView: View {
@AppStorage("calBudget") var calBudget = "1700"
@AppStorage("calsBudget") var calsBudget = 0
var body: some View {
NavigationView {
Form {
Text("Budget: \(self.calBudget)")
Text("to integer \(String(self.calsBudget))")
}.toolbar {
ToolbarItem() {
NavigationLink( destination: UserSettings(calBudget: $calBudget, calsBudget: $calsBudget)) { Text("settings") }
}
}
}
}
}
struct UserSettings: View {
@Binding var calBudget: String
@Binding var calsBudget: Int
var body: some View {
Form {
HStack {
TextField("Budget: ", text: self.$calBudget)
Button(action: {
let calsBudget: Int = Int(self.calBudget ) ?? 1000
}) { Text("make into integer")}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView( )
}
}
the first problem is the Integer conversion is not working with my code
This is your code currently:
let calsBudget: Int = Int(self.calBudget ) ?? 1000
Here, you're creating a new constant, calsBudget
. Then you do nothing with it, throwing it away. Instead, you want to modify the existing @Binding var calsBudget: Int
, so assign the value.
calsBudget = Int(self.calBudget ) ?? 1000
The second problem is, every keystroke in the UserSettings view is generating a new UserSettings view creating a bunch of nested views
This happens because of this code:
.toolbar {
ToolbarItem() {
NavigationLink( destination: UserSettings(calBudget: $calBudget, calsBudget: $calsBudget)) { Text("settings") }
}
}
NavigationLink
must always be inside a NavigationView
. Whenever you put it outside, for example in a toolbar
, you'll run into weird issues.
Here's the fixed code:
struct ContentView: View {
@AppStorage("calBudget") var calBudget = "1700"
@AppStorage("calsBudget") var calsBudget = 0
@State var settingsPresented = false
var body: some View {
NavigationView {
/// NavigationView must only contain 1 view, so wrap Form and NavigationLink inside VStack
VStack {
Form {
Text("Budget: \(self.calBudget)")
Text("to integer \(String(self.calsBudget))")
}
/// NavigationLink must be inside NavigationView
NavigationLink(
destination: UserSettings(calBudget: $calBudget, calsBudget: $calsBudget),
isActive: $settingsPresented) /// activates when `settingsPresented` is true
{ EmptyView() }
}
.toolbar {
ToolbarItem() {
Button("settings") {
settingsPresented = true /// activate the NavigationLink
}
}
}
}
}
}
struct UserSettings: View {
@Binding var calBudget: String
@Binding var calsBudget: Int
var body: some View {
Form {
HStack {
TextField("Budget: ", text: self.$calBudget)
Button(action: {
calsBudget = Int(self.calBudget ) ?? 1000 /// assign value, not create
}) { Text("make into integer")}
}
}
}
}