Open onmyway133 opened 3 years ago
Use custom Binding and validate the text. In case of zero, return empty string to let TextField display placeholder
var textField: some View { let text = Binding<String>( get: { state.amount > 0 ? "$\(state.amount)" : "" }, set: { text in let text = text.replacingOccurrences(of: "$", with: "") state.amount = Int(text) ?? 0 } ) return TextField("$0", text: text) .keyboardType(.numberPad) .font(.system(size: 50, weight: .medium, design: .monospaced)) .foregroundColor(Asset.textPrimary.color) .multilineTextAlignment(.center) .accentColor(Asset.primary.color) }
We can also use NumberFormatter for more customizable control
private extension NumberFormatter { static let currency: NumberFormatter = { let formatter = NumberFormatter() formatter.maximumFractionDigits = 2 formatter.minimumFractionDigits = 0 return formatter }() }
For decimal pad, and to avoid overflow, we can have some checks
let text = Binding<String>( get: { if state.payment.amount > 0 { let number = NSNumber(value: state.payment.amount) let string = NumberFormatter.currency.string(from: number) ?? "" return "$\(string)" } else { return "" } }, set: { text in let text = text.replacingOccurrences(of: "$", with: "") if text.hasSuffix(".") { return } let amount = Amount(text) ?? 0 // Avoid TextField to overgrow outside frame if amount < 10_000 { state.payment.amount = amount } else { state.payment.amount = state.payment.amount } } )
Use custom Binding and validate the text. In case of zero, return empty string to let TextField display placeholder
We can also use NumberFormatter for more customizable control
For decimal pad, and to avoid overflow, we can have some checks