【问题标题】:How to update the values of a struct in a View如何更新视图中结构的值
【发布时间】:2020-05-23 19:20:32
【问题描述】:

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

我设法制作了结构并将其引入视图中,但我无法更改它的值。结构的值应根据用户在视图上所做的操作以及他们添加到其中的信息进行更新。 我做了一个简单的视图,在 TextField 中输入的任何内容都将添加到结构的属性之一中。 对于下面的代码,我得到 Cannot assign to property: 'self' is immutable

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

知道如何解决这个问题,以便我可以与结构交互并更新其属性。我也会在其他视图中使用这个结构变量。

提前致谢

【问题讨论】:

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


    【解决方案1】:

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

    class RecipeViewModel: ObservableObject {
       @Published var 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")
                }
            }
        }
    }
    

    【讨论】:

    • 这很好,我会将其标记为答案。谢谢。但是,您能否解释一下如何在另一个视图中访问 recipeVM 中的数据?
    • @Danny,recipeVM 是一个引用,因此您可以通过构造函数或作为环境对象或作为其他引用类型对象的成员将其注入另一个视图。
    【解决方案2】:

    添加@State

    @State var recipe = Recipe(..
    

    另外,不要忘记在按钮操作中使用recipe 之前添加self.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-09
      • 2022-01-24
      • 2018-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多