According to this article it should be simple to create custom Binding with different type for binding and for display. This is my not working example:
import SwiftUI
struct BindingButton: View {
@Binding var title: String
var onTap: () -> Void
var body: some View {
Button {
onTap()
} label: {
Text(title)
}
}
}
struct CustomBinding: View {
@State var date: Date
@State var int: Int
lazy var descriptiveDate = Binding(
get: { //Escaping closure captures mutating 'self' parameter
return self.date.description
},
set: { _ in }
)
lazy var descriptiveInt = Binding(
get: { //Escaping closure captures mutating 'self' parameter
return String(self.int)
},
set: { _ in }
)
var body: some View {
VStack {
// Cannot find '$descriptiveDate' in scope
BindingButton(title: $descriptiveDate) {
date = Date()
}
// Cannot find '$descriptiveInt' in scope
BindingButton(title: $descriptiveInt) {
int += 2
}
}
}
}
I would like to bind Date and Int, but use string for display. Is it possible witohut Double Binding? I mean I would like to avoid to create first Binding for Date and Int, then .onChange
update another Binding for String and String. Do I have to do it like this, or maybe there is more elegant way?
2
Answers
Binding
is by definition a two-way connection.lazy
implies that the code only runs once. Based on this and the emptyset
yourdescriptiveDate
anddescriptiveInt
don’t need to beBinding
just aget
for aString
lazy
doesn’t work with withSwiftUI
View
s when@State
triggers a redraw you need to recalculate thebody
and descriptive variables.I totally agree with the previous answer that in this case the binding is not needed. But to address the other part of the question: "Is it possible to have interdependent
@State
and@Binding
without Double Binding?"Well, first of all, even in the most primitive way, you don’t need a custom binding. Instead you can use 2 state variables:
and utilize either
didSet
:Or have
onChange
implemented fordate
andint
state:But this is still a bit redundant, as you will have duplication of the
@State
for every variable. So to avoid that custom binding is helpful:That is: you don’t need to keep additional state for each state, while still have a possibility to change parent value from child. Doesn’t make much sense in this concrete example, but it does in some cases.
So did we avoid "double" variable – not really. Since you have 2 pieces of information that can change following some rules, but independently, you do need 2 of something. But custom binding is just one of the possibilities.