How can I use Binding(get: { }, set: { })
custom binding with @Binding
property on SwiftUI view. I have used this custom binding successfully with @State
variable but doesn't know how to apply it to @Binding
in subview initializer. I need it to observe changes assigned to @Binding
property by parent class in order to execute code with some side effects!
In SwiftUI, you can create bindings in 2 ways: With the @Binding property wrapper, which creates a binding, but doesn't store it. With other property wrappers, like @State, which creates a binding, and also stores its value.
Create a new custom binding by creating an instance of the CustomBinding class and passing the collection outputBec to the constructor. The resulting custom binding shares many of the same characteristics as the standard WSHttpBinding.
@State property wrappers are used to read and write variables from a structure. It is used in single view and is recommended that you set its property as private so that other views cannot access it. @Binding property wrappers are used to access variables from other views.
String in swift is a value type, so your textValue property is taking a copy of the value, and SwiftUI is monitoring that copy, not the actual value in Controller.message . What you want here is a binding or an observed object—exactly which depends on whether Controller is a struct or a class type.
Here is possible approach. The demo shows two-directional channel through adapter binding between main & dependent views. Due to many possible callback on update there might be needed to introduce redundancy filtering, but that depends of what is really required and out of scope.
Demo code:
struct TestBindingIntercept: View {
@State var text = "Demo"
var body: some View {
VStack {
Text("Current: \(text)")
TextField("", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
Divider()
DependentView(value: $text)
}
}
}
struct DependentView: View {
@Binding var value: String
private var adapterValue: Binding<String> {
Binding<String>(get: {
self.willUpdate()
return self.value
}, set: {
self.value = $0
self.didModify()
})
}
var body: some View {
VStack {
Text("In Next: \(adapterValue.wrappedValue)")
TextField("", text: adapterValue)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
private func willUpdate() {
print(">> run before UI update")
}
private func didModify() {
print(">> run after local modify")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With