0

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

Luca
  • 25
  • 4

1 Answers1

2

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
}
Valerika
  • 366
  • 1
  • 3
  • 8
  • Thanks. The only drawback I noticed by using struct instead class for Food is that the editor preview doesn't work fine for FoodView: for example if I place 2 TextField with $food.name they don't stay synchronized. – Luca Jul 21 '21 at 12:43
  • Probably you use a "constant" to preview the Binding. Try to implement a View Wrapper. I added code to the answer. – Valerika Jul 21 '21 at 15:51