Scenario:
In SwiftUI
, my TextField
has a Double
value. On tapping/focusing the TextField
the current Double
value is cleared, to allow the user to easily enter a new value without having to select and delete the current value. If the user does not enter a new value, the old value is restored on deselect.
Issue
Utilising .focused()
and .onChange(of:)
this does not appear to be possible. Below code correctly clears the value (visible in console). However, the change is not reflected within the UI. Forcing the UI to update by utilising .id()
on the TextField
deselects the TextField
, making this workaround useless.
Why does the UI not update from the change to the TextField
value property?
struct ContentView: View {
@FocusState var focus: Bool
@State var test: Double? = 100
@State var id: UUID = UUID()
var body: some View {
VStack {
TextField("Placeholder", value: $test, format: .number)
.id(id)
.focused($focus)
.onChange(of: focus, perform: { editing in
var oldValue: Double? = test
if editing {
self.$test.wrappedValue = nil
self.$id.wrappedValue = UUID()
} else {
if test == nil {
self.$test.wrappedValue = oldValue
self.$id.wrappedValue = UUID()
}
}
})
}
.padding()
}
}
Is there a way to do this with SwiftUI
‘s TextField
?
2
Answers
Extending on @meomeomeo' answer, please find a reusable
TextField
view below that satisfies the need for theTextField
text to be of typeDouble
.The second
.onChange(of:)
updates the input binding as the user is typing but only if the typed text is of typeDouble
. This is in case the user never deselects theTextField
before e.g. saving.Why UI not update from the change to the TextField value ?
Because it doesn’t bind TextField’s value (String) to your value (Double) directly.
To
clear value on focus, restore on deselect
, you need to do it on TextField with text, not value. Here’s an example:If you want to make it Double only, handle it outside (in ViewModel or something)