SwiftUI 无法将字符串从 Appstorage 转换为 Int。此外,在更新第二个视图时,它会在每次击键后创建一个新视图

SwiftUI unable to convert string from Appstorage into Int. Also while updating the second view it is creating a new view after every every keystroke

SwiftUI 新手。

我想在 UserSettings 视图中更改字符串 calBudget,并在 ContentView 中将其转换为 Int。第一个问题是整数转换不适用于我的代码。第二个问题是,UserSettings 视图中的每个击键都会生成一个新的 UserSettings 视图,从而创建一堆嵌套视图。

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

这是您当前的代码:

let calsBudget: Int = Int(self.calBudget ) ?? 1000

在这里,您正在创建一个新常量 calsBudget。然后你什么也不做,把它扔掉。相反,您想修改现有的 @Binding var calsBudget: Int,因此分配值。

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

这是因为这段代码:

.toolbar {
    ToolbarItem() {
        NavigationLink( destination: UserSettings(calBudget: $calBudget, calsBudget: $calsBudget)) { Text("settings") }
    }
}

NavigationLink 必须 始终在 NavigationView 内。每当你把它放在外面时,例如在 toolbar 中,你将 运行 变成 .

固定代码如下:

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")}
            
            }
        }
    }
}