Hi! I'm get starting to learn about TCA and I'm have the follow scenario:
I need to get a text from a textfield in SwiftUI and in other scenario, i needed to use @State var varName to get the current text on my TextField.
How can I do this?
Check out the "bindings basics" example from the SwiftUI case studies demo: swift-composable-architecture/01-GettingStarted-Bindings-Basics.swift at 8cc8492b9f3930491e74d2579584c1e9d20bedb0 · pointfreeco/swift-composable-architecture · GitHub
Because TCA does unidirectional data flow, you must define an action to mutate state. In this case we have a text field with an associated text
state:
Any SwiftUI component that requires a Binding to do its job can be used in the Composable \
Architecture. You can derive a Binding from your ViewStore by using the `binding` method. This \
will allow you to specify what state renders the component, and what action to send when the \
component changes, which means you can keep using a unidirectional style for your feature.
"""
// The state for this screen holds a bunch of values that will drive
struct BindingBasicsState: Equatable {
var sliderValue = 5.0
var stepCount = 10
var text = ""
var toggleIsOn = false
}
enum BindingBasicsAction {
case sliderValueChanged(Double)
case stepCountChanged(Int)
case textChange(String)
case toggleChange(isOn: Bool)
}
textChange
action:
struct BindingBasicsState: Equatable {
var sliderValue = 5.0
var stepCount = 10
var text = ""
var toggleIsOn = false
}
enum BindingBasicsAction {
case sliderValueChanged(Double)
case stepCountChanged(Int)
case textChange(String)
case toggleChange(isOn: Bool)
}
struct BindingBasicsEnvironment {}
let bindingBasicsReducer = Reducer<
BindingBasicsState, BindingBasicsAction, BindingBasicsEnvironment
> {
state, action, _ in
switch action {
The reducer updates state with the action:
And in the view, the view store derives a binding by describing the state and action:
struct BindingBasicsView: View {
let store: Store<BindingBasicsState, BindingBasicsAction>
var body: some View {
WithViewStore(self.store) { viewStore in
Form {
Section(header: Text(template: readMe, .caption)) {
HStack {
TextField(
"Type here",
text: viewStore.binding(get: { $0.text }, send: BindingBasicsAction.textChange)
)
.disableAutocorrection(true)
.foregroundColor(viewStore.toggleIsOn ? .gray : .primary)
Text(alternate(viewStore.text))
}
.disabled(viewStore.toggleIsOn)
Toggle(
isOn: viewStore.binding(get: { $0.toggleIsOn }, send: BindingBasicsAction.toggleChange)
) {
While there are a few steps to get there, once set up you can fully control the stream of text field events and do a lot of interesting, testable things!
Yes, I read about binding but I'm trying to bind a text only when I did tap a button. Something like this:
hey @stephencelis thanks!
Finally I understood!