Combineを使うと割とスッキリ実装できる。
今回のサンプルは日本円のみにしてますが、応用して通貨以外にも色々な単位に自動変換するUITextFieldを作れると思います。
class SampleViewController: UIViewController {
let numberFormatter: NumberFormatter = {
let nf = NumberFormatter()
nf.numberStyle = .currency
nf.locale = Locale(identifier: "ja_JP")
return nf
}()
let textField: UITextField = {
let tf = UITextField()
tf.keyboardType = .numberPad
return tf
}()
private var cancellable = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
textField
.textDidChangePublisher()
.map { Int($0.removeCurrencyCharacter()) ?? 0 }
.map { self.numberFormatter.string(from: NSNumber(value: $0)) }
.assign(to: \.text, on: textField)
.store(in: &cancellable)
}
extension UITextField {
func textDidChangePublisher() -> AnyPublisher<String, Never> {
NotificationCenter.default
.publisher(for: UITextField.textDidChangeNotification, object: self)
.compactMap { ($0.object as? UITextField)?.text }
.eraseToAnyPublisher()
}
}
extension String {
func removeCurrencyCharacter() -> String {
self.replacingOccurrences(of: ",", with: "")
.replacingOccurrences(of: "¥", with: "")
}
}