I use SwiftUI TextField
to edit a backing object property. As I type, the TextField invokes format parser and updates the backing property on every character I type, before I’ve completed the input. This intermediate input is uninteresting at best, and quite distracting at worst.
I’d like the TextField to accept any input until submit or loss of focus, and then apply format parser and update the backing property. Is there a way to do that in SwiftUI?
In Cocoa/Objective-C, I used NSBindingOption.continuouslyUpdatesValue
set to false.
@State var text: String = "Hello"
var body: some View {
Text(text) // This shows updated value on every input character.
TextField("Text: ", text: $text)
.continuouslyUpdatesValue(false) // I’d like to have something like this
You can write a TextField
wrapper that uses its internal @State
struct NonContinuousTextField: View {
let title: LocalizedStringKey
@Binding var text: String
@State private var internalText = ""
@State private var appeared = false
init(_ title: LocalizedStringKey, text: Binding<String>) {
self.title = title
self._text = text
}
@FocusState var focused: Bool
var body: some View {
TextField(title, text: $internalText)
.onAppear { // initialise internalText
if !appeared {
internalText = text
appeared = true
}
}
.focused($focused)
.onSubmit {
text = internalText
}
.onChange(of: focused) { _, newValue in
if !newValue { // lose focus
text = internalText
}
}
}
}