Swift didSet for var that gets changed in child with @Binding

Viewed 559

I have something of the following:

struct ContentView: View {
    @State var a = 0 {
        didSet {
            print("Change detected in Parent")
        }
    }
    var body: some View {
        VStack{
            Text(String(self.a))
            Content2(a: self.$a)
        }
    }
}

struct Content2: View {
    @Binding var a: Int {
        didSet {
            print("Change detected in Child")
        }
    }

    var body: some View {
        Text(String(a)).onTapGesture {
            if self.a == 1 {
                self.a = 2
            }else {
                self.a = 1
            }

        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


Why is the didSet of the parent never called? As it is clearly changing. How can I make sure it gets called or notified in some other way?

It is important to me to take notice of the change on the ContentView and not outsource this to a PublishableObject. As I want to make further changes on the ContentView once this change has been detected. Catching the didSet on an outsourced Class would not help.

To clear things up my use case is as follows: I am counting up a Int on the child View. Once this Int reached a certain number it should trigger a new Firebase getDocuments function on the ParentView.

1 Answers

Here is a solution for your use-case

struct ContentView_: View {
    @State var a = 0

    var body: some View {
        let counterBinding = Binding( // << proxy biding
            get: { self.a },
            set: {
                self.a = $0  // decision case below
//                if $0 > CONSTANT {
//                   // ... call getDocuments here
//                }
            }
        )
        return VStack{
            Text(String(self.a))
            Content2(a: counterBinding) // inject proxy !!
        }
    }
}

struct Content2: View {
    @Binding var a: Int

    var body: some View {
        Text(String(a)).onTapGesture {
            if self.a == 1 {
                self.a = 2
            }else {
                self.a = 1
            }
        }
    }
}
Related