如何解决如何使用户仅在 SwiftUI 文本字段中输入数字货币,同时保留 $ 和 .?
现在,我有以下几点:
private var currencyFormatter: NumberFormatter = {
let f = NumberFormatter()
// allow no currency symbol,extra digits,etc
f.isLenient = true
f.numberStyle = .currency
return f
}()
TextField("Total",value: $totalInput,formatter: currencyFormatter)
.font(.largeTitle)
.padding()
.background(Color.white)
.foregroundColor(Color.black)
.multilineTextAlignment(.center)
我希望文本字段以 $0.00 作为占位符开始,但是当用户开始输入时,前两个输入将以美分填充...因此 5055 将逐渐显示为:
第 1 步(用户点击 5 次):0.05 美元
第 2 步(用户点击 0):$0.50
第 3 步(用户点击 5):$5.05
第 4 步(用户点击 5):50.55 美元
如果金额超过 999 美元,则会插入逗号。
如何做到这一点?现在我的 totalInput 类型是 Double?。
解决方法
要创建一个允许用户从右到左输入金额的货币字段,您需要一个可观察对象(绑定管理器)、一个货币数字格式化程序,并在每次使用 onChange 方法更改值时进行观察:
import SwiftUI
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ContentView: View {
@ObservedObject private var bindingManager = TextBindingManager(amount: 0)
var decimal: Decimal { bindingManager.text.decimal / pow(10,Formatter.currency.maximumFractionDigits) }
var maximum: Decimal = 999_999_999.99
@State private var lastValue: String = ""
@State private var locale: Locale = .current {
didSet { Formatter.currency.locale = locale }
}
var body: some View {
VStack(alignment: .leading) {
TextField(bindingManager.text,text: $bindingManager.text)
.keyboardType(.numberPad)
.multilineTextAlignment(.trailing) // this will keep the text aligned to the right
.onChange(of: bindingManager.text) { string in
if string.decimal > maximum {
self.bindingManager.text = lastValue
} else {
self.bindingManager.text = decimal.currency
lastValue = self.bindingManager.text
}
return
}
}
.padding()
.onAppear {
Formatter.currency.locale = locale
}
}
}
class TextBindingManager: ObservableObject {
@Published var text: String = ""
var amount: Decimal = .zero
init(amount: Decimal) {
self.amount = amount
self.text = Formatter.currency.string(for: amount) ?? "$0.00"
}
}
fileprivate extension Formatter {
static let currency: NumberFormatter = .init(numberStyle: .currency)
}
extension NumberFormatter {
convenience init(numberStyle: Style) {
self.init()
self.numberStyle = numberStyle
}
}
extension StringProtocol where Self: RangeReplaceableCollection {
var digits: Self { filter (\.isWholeNumber) }
}
extension String {
var decimal: Decimal { Decimal(string: digits) ?? 0 }
}
extension Decimal {
var currency: String { Formatter.currency.string(for: self) ?? "" }
}
这是相当于我为 UIKit 实现的自定义 CurrencyField 的 SwiftUI。
,我创建了一个环绕 UITextfield 的组件。
您可以在这里查看https://github.com/youjinp/SwiftUIKit
这是演示
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。