In SwiftUI I have a struct that want to hold data of the View. Let's say there is a View that user can create a recipe in it. It has a text field to type the recipe name, and options to choose and add to the array in the struct's properties.
I managed to make the struct and introduce it in the View but I cannot change it values. The values of the struct should be updated based on what users does on the View and the info they add to it. I made a simple View that whatever is entered in the TextField will be added in one of the properties of the struct. For the below code I get 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
}
VIEW:
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")
}
}
}
}
Any idea how to solve this so I can interact with the struct and update its properties. I will use this struct variable in other Views as well.
Thanks in advance
For the use-case as provided the most appropriate is to use view model as in example below
class RecipeViewModel: ObservableObject {
@Published var recipe: Recipe
init(_ recipe: Recipe) {
self.recipe = recipe
}
}
so in the view
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")
}
}
}
}