Skip to content

Instantly share code, notes, and snippets.

@daniloc
Last active April 10, 2023 17:01
Show Gist options
  • Save daniloc/254db4eb8e009acc2409edc2da2f18ac to your computer and use it in GitHub Desktop.
Save daniloc/254db4eb8e009acc2409edc2da2f18ac to your computer and use it in GitHub Desktop.
SwiftUI TextField for decimal input
struct DecimalTextField: View {
@Binding var decimalValue: Decimal
@State var clearValue: Decimal = 1
var clearValueString: String {
return String("\(clearValue)")
}
@State private var lastValidInput: String?
let localizedSeparator = NumberFormatter().decimalSeparator!
var inputValidator: Binding<String> {
//adapted from: https://stackoverflow.com/a/58031510/150181
Binding<String>(
get: { self.lastValidInput ?? String("\(self.decimalValue)") },
set: {
let matchesInputFormat = $0.range(of: "^[0-9]{0,9}([\(self.localizedSeparator)][0-9]{0,9})?$", options: .regularExpression) != nil
//adapted from https://stackoverflow.com/a/54381284/150181
if matchesInputFormat {
self.decimalValue = Decimal(string: $0) ?? self.clearValue
self.lastValidInput = $0
} else {
self.inputValidator.wrappedValue = self.lastValidInput ?? self.clearValueString
}
})
}
var body: some View {
HStack {
TextField("", text: inputValidator)
.keyboardType(.decimalPad)
Button(action: {
self.inputValidator.wrappedValue = self.clearValueString
}) {
Image(systemName: "xmark.circle.fill")
.accentColor(.secondary)
}
}
}
}
@daniloc
Copy link
Author

daniloc commented Mar 24, 2020

This may be stupid—it's my first SwiftUI component, so no guarantees. Still, solves the problem of decimal input with user-friendly validation. All you have to do is pass it a Decimal binding:

DecimalTextField(decimalValue: $reference.decimal)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment