如何在视图中更新结构的值

时间:2020-05-23 19:20:32

标签: swift struct swiftui swift-structs swift-class

在SwiftUI中,我有一个要保存View数据的结构。假设有一个用户可以在其中创建配方的视图。它具有一个用于输入配方名称的文本字段,以及用于选择并添加到结构属性中的数组的选项。

我设法制作了该结构并将其引入到View中,但是我无法更改其值。应该根据用户在View上执行的操作以及他们添加到View的信息来更新struct的值。 我做了一个简单的视图,将在TextField中输入的任何内容都添加到该结构的属性之一中。 对于以下代码,我无法分配属性:'self'是不可变的

struct Recipe: Codable {
let user: Int
var recipeName, createdDate: String
let ingredients: [Ingredient]
let equipment: [[Int]]

enum CodingKeys: String, CodingKey {
    case user = "User"
    case recipeName = "RecipeName"
    case createdDate
    case ingredients = "Ingredients"
    case equipment = "Equipment"
 }
}

struct Ingredient: Codable {
   let ingredient, size: Int
}

查看:

struct ContentView: View {
    var recipe = Recipe(user: 1231, recipeName: "Recipe Name", createdDate: "SomeDate", ingredients: [Ingredient(ingredient: 1, size: 2)], equipment: [[1],[4],[5]])


    var body: some View {
        VStack {
            Text(self.recipe.recipeName)
            Button(action: {
                recipe.recipeName = "New Name" //Cannot assign to property: 'self' is immutable
            }) {
                Text("Change Name")
            }
        }
    }
}

任何想法如何解决这个问题,以便我可以与该结构进行交互并更新其属性。我还将在其他视图中使用此struct变量。

预先感谢

2 个答案:

答案 0 :(得分:1)

添加({:x 1} :x) ;=> 1

@State

此外,在按钮操作中使用@State var recipe = Recipe(.. 之前,请不要忘记添加self.

答案 1 :(得分:1)

对于所提供的用例,最合适的是使用以下示例中的视图模型

class RecipeViewModel: ObservableObject {
   @Published recipe: Recipe
   init(_ recipe: Recipe) {
     self.recipe = recipe
   }
}

所以在视野

struct ContentView: View {
    @ObservedObject var recipeVM = RecipeViewModel(Recipe(user: 1231, recipeName: "Recipe Name", createdDate: "SomeDate", ingredients: [Ingredient(ingredient: 1, size: 2)], equipment: [[1],[4],[5]]))


    var body: some View {
        VStack {
            Text(self.recipeVM.recipe.recipeName)
            Button(action: {
                self.recipeVM.recipe.recipeName = "New Name"
            }) {
                Text("Change Name")
            }
        }
    }
}