The Problem:
You want to write a custom SwiftUI TextField that automatically formats user input as a credit card number in the format xxxx-xxxx-xxxx-xxxx. You’re unsure how to update the original text field value with the formatted string.
The Solutions:
Solution 2: Typing in Credit Card Numbers
To format the TextField input into credit card format ("xxxx-xxxx-xxxx-xxxx"), we can implement a custom CreditCardTextField
using UIViewRepresentable
. Here’s how:
1. Formatting Helper Method:
private static func formatCreditCardNumber(_ number: String) -> String {
let formattedNumber = number
.components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
.replacingOccurrences(of: "(.{4})", with: "$1 ", options: .regularExpression, range: nil)
.trimmingCharacters(in: .whitespacesAndNewlines)
return formattedNumber
}
2. CreditCardTextField
:
struct CreditCardTextField: UIViewRepresentable {
@Binding var number: String
private var didChange: ((String) -> Void)?
init(number: Binding<String>, didChange: @escaping (String) -> Void = { _ in }) {
self._number = number
self.didChange = didChange
}
func makeUIView(context: Context) -> UITextField {
let textField = UITextField()
textField.keyboardType = .numberPad
textField.addTarget(context.coordinator, action: #selector(Coordinator.textChanged), for: .editingChanged)
return textField
}
func updateUIView(_ textField: UITextField, context: Context) {
// Avoid infinite loop
if textField.text == number { return }
textField.text = CreditCardTextField.formatCreditCardNumber(number)
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITextFieldDelegate {
var parent: CreditCardTextField
init(_ parent: CreditCardTextField) {
self.parent = parent
}
@objc func textChanged(sender: UITextField) {
parent.number = sender.text ?? ""
parent.didChange?(parent.number)
}
}
}
3. Usage:
In your ContentView
, you can use the CreditCardTextField
like this:
struct ContentView: View {
@State var cardNumber = ""
var body: some View {
VStack {
CreditCardTextField(number: $cardNumber)
.frame(height: 50)
.border(.black)
}
.padding()
}
}
This solution provides a more streamlined and efficient way to format credit card input. It separates the formatting logic into a static method and eliminates the need for a Coordinator
, resulting in a simpler and more maintainable implementation.
Q&A
How do you apply formats to the Text Field and write the updated code ?
Set up a method for formatting the text that takes a string and transform the string, so that the formatting could be static and reused at different places if needed.
How to give an update to the UIView?
Update the UI view it the TextField already has a formatted number and if it doesn’t format the number and set value to it’s binding.
Video Explanation:
The following video, titled "SwiftUI Credit/Debit Card Input Form - Move to Next TextField", provides additional insights and in-depth exploration related to the topics discussed in this post.
Hello Guys In this video, I'm going to show how to create a credit/debit card input in a stylish manner with keyboard binding via ...
The following video, titled "SwiftUI Credit/Debit Card Input Form - Move to Next TextField", provides additional insights and in-depth exploration related to the topics discussed in this post.
Hello Guys In this video, I'm going to show how to create a credit/debit card input in a stylish manner with keyboard binding via ...