Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

didSet for a @Binding var in Swift

Normally we can use didSet in swift to monitor the updates of a variable. But it didn't work for a @Binding variable. For example, I have the following code:

@Binding var text {
   didSet {
       ......
   }
}

But the didSet is never been called.Any idea? Thanks.

like image 698
Bagusflyer Avatar asked Sep 16 '19 08:09

Bagusflyer


2 Answers

You shouldn’t need a didSet observer on a @Binding.

If you want a didSet because you want to compute something else for display when text changes, just compute it. For example, if you want to display the count of characters in text:

struct ContentView: View {
    @Binding var text: String

    var count: Int { text.count }

    var body: some View {
        VStack {
            Text(text)
            Text(“count: \(count)”)
        }
    }
}

If you want to observe text because you want to make some other change to your data model, then observing the change from your View is wrong. You should be observing the change from elsewhere in your model, or in a controller object, not from your View. Remember that your View is a value type, not a reference type. SwiftUI creates it when needed, and might store multiple copies of it, or no copies at all.

like image 71
rob mayoff Avatar answered Oct 19 '22 17:10

rob mayoff


Instead of didSet you can always use onReceive (iOS 13+) or onChange (iOS 14+):

import Combine
import SwiftUI

struct ContentView: View {
    @State private var counter = 1
    
    var body: some View {
        ChildView(counter: $counter)
        Button("Increment") {
            counter += 1
        }
    }
}

struct ChildView: View {
    @Binding var counter: Int
    
    var body: some View {
        Text(String(counter))
            .onReceive(Just(counter)) { value in
                print("onReceive: \(value)")
            }
            .onChange(of: counter) { value in
                print("onChange: \(value)")
            }
    }
}
like image 13
pawello2222 Avatar answered Oct 19 '22 17:10

pawello2222