How can I mutate inputted textField's String with binding action?? #3062
-
Hellow everyone! My development eviroment
I want to muate inputted textField's String. ex) lowercased, trimmingCharacters, prefix... I referenced Working with SwiftUI bindings I tried three ways but not works😂 first trystruct ContentView: View {
@Perception.Bindable private var store: StoreOf<ContentFeature>
init(store: StoreOf<ContentFeature>) {
self.store = store
}
var body: some View {
WithPerceptionTracking {
VStack {
TextField("test", text: $store.textFieldText.sending(\.textInpuuted))
}
.padding()
}
}
}
@Reducer
struct ContentFeature {
@ObservableState
struct State: Equatable {
var textFieldText: String
}
enum Action: BindableAction {
case binding(BindingAction<State>)
case textInpuuted(String)
}
var body: some ReducerOf<Self> {
BindingReducer()
Reduce<State, Action> { state, action in
switch action {
case let .textInpuuted(text):
let newText = text.lowercased()
state.textFieldText = newText
return .none
default:
return .none
}
}
}
} second trystruct ContentView: View {
@Perception.Bindable private var store: StoreOf<ContentFeature>
init(store: StoreOf<ContentFeature>) {
self.store = store
}
var body: some View {
WithPerceptionTracking {
VStack {
TextField("test", text: $store.textFieldText)
}
.padding()
}
}
}
@Reducer
struct ContentFeature {
@ObservableState
struct State: Equatable {
var textFieldText: String
}
enum Action: BindableAction {
case binding(BindingAction<State>)
case textInpuuted(String)
}
var body: some ReducerOf<Self> {
BindingReducer()
Reduce<State, Action> { state, action in
switch action {
case .binding(\.textFieldText):
let newText = state.textFieldText.lowercased()
state.textFieldText = newText
return .none
default:
return .none
}
}
}
} thrid tryimport SwiftUI
import ComposableArchitecture
struct ContentView: View {
@Perception.Bindable private var store: StoreOf<ContentFeature>
init(store: StoreOf<ContentFeature>) {
self.store = store
}
var body: some View {
WithPerceptionTracking {
VStack {
TextField("test", text: $store.textFieldText)
}
.padding()
}
}
}
@Reducer
struct ContentFeature {
@ObservableState
struct State: Equatable {
var textFieldText: String
}
enum Action: BindableAction {
case binding(BindingAction<State>)
case textInpuuted(String)
}
var body: some ReducerOf<Self> {
BindingReducer()
.onChange(of: \.textFieldText) { oldValue, newValue in
Reduce<State, Action> { state, action in
state.textFieldText = state.textFieldText.lowercased()
return .none
}
}
Reduce<State, Action> { state, action in
switch action {
default:
return .none
}
}
}
} I also referenced Performance as I read sending actions is not lightweight so mutating inputted string every time looks not good. Is there any good way mutating inpuuted string?? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 8 replies
-
Hi @JongHoooon, this is just a limitation of SwiftUI in general. If you were to recreate this app using either @Observable
class Model {
var text = "hello" {
didSet {
if text != text.lowercased() {
text = dump(text.lowercased())
}
}
}
}
struct A: View {
@Bindable var model = Model()
var body: some View {
Form {
TextField("", text: $model.text)
}
}
} I believe the way SwiftUI wants you to do these kinds of transformations is through formatters, which is an additional argument you can pass to |
Beta Was this translation helpful? Give feedback.
-
I've found the same problem. In my case I wanted to limit the length of the String that is typed by the user. I need to modify the length of the String so that when the user erases one character, the character is deleted from the limited-length String. Did you find a solution to this? |
Beta Was this translation helpful? Give feedback.
-
@JongHoooon @alvarezGarciaMarcos @mbrandonw |
Beta Was this translation helpful? Give feedback.
That trick seems good to me!