0
votes

I have 2 models: Bag and Food. A Bag contains 1 Food. The Food has a name.

I'm trying to bind the Food.name property with a TextField showed in the parent view (BagView) and another TextField showed in the child view (FoodView).

  • When I edit the parent's text field the change is showed in bot the views.
  • When I edit the child's text field the change is not showed in the parent view. Why?

Here is my sample code:

class Bag: ObservableObject {
    @Published var food: Food
    
    init(food: Food) {
        self.food = food
    }
}

class Food: ObservableObject {
    @Published var name: String
    
    init(name: String) {
        self.name = name
    }
}

struct BagView: View {
    @ObservedObject var bag: Bag
    
    var body: some View {
        VStack {
            TextField("Placeholder 1", text: $bag.food.name)
            FoodView(food: bag.food)
        }
    }
}

struct FoodView: View {
    @ObservedObject var food: Food
    
    var body: some View {
        TextField("Placeholder 2", text: $food.name)
    }
}

enter image description here

1

1 Answers

2
votes

To pass data between two views you need to use Binding for the FoodView.

struct BagView: View {
    @ObservedObject var bag: Bag

    var body: some View {
        VStack {
            TextField("Placeholder 1", text: $bag.food.name)
            FoodView(food: $bag.food)
        }
    }
}

struct FoodView: View {
    @Binding var food: Food
    
    var body: some View {
        TextField("Placeholder 2", text: $food.name)
    }
}

Answering on your comment I recommend to add an additional view / wrapper to preview Binding. enter image description here

P.s. By the way if you are going to use Food as a part of the Bag view model, you don't need to make it class with Published properties. Structure is enough.

struct Food {
    var name: String
}