SwiftUI TextField 货币格式问题

问题描述 投票:0回答:3

我在使用 TextField 输入货币金额时遇到了 SwiftUI 最终用户的可用性问题。

绑定字段为双精度型,初始设置为0,显示文本字段时提示为$0.00。

问题是,当用户想要输入一个值时,他们必须手动使用退格键删除 0.00。另外,如果他们不小心在 $ 符号上退格,则此后输入的任何值都会消失!

当存在多个货币字段时,这对最终用户来说是一个真正的麻烦。

我在互联网上看到了在 NumberFormatter 中设置

formatter.zeroSymbol = ""
的建议,但是当
numberStyle = .currency
时,输入的任何值都会丢失/损坏。

如果我将数字样式更改为

.decimal
,我可以使用
zeroSymbol
选项,它似乎可以工作,但我会丢失货币格式。

有谁知道如何解决这个问题吗?

以下是您可以运行的示例代码来演示此问题。


import SwiftUI

struct ContentView: View {
    @State private var amount: Double = 0
    
    let currencyFormat: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        //                formatter.zeroSymbol = ""
        return formatter
    }()

    var body: some View {
        HStack {
            Text("Enter Amount")
            Spacer()
            TextField("", value: $amount, formatter: currencyFormat)
                .keyboardType(.numbersAndPunctuation)
        }
        .padding()
        
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

swiftui formatting textfield currency usability
3个回答
5
投票

详细阐述@Zulqarnain Naveed 的答案:

TextField("",value: $amount, format: .currency(code: Locale.current.currency?.identifier ?? "USD"))

添加以下代码行。当聚焦时,这将选择文本字段中的所有文本:

.onReceive(NotificationCenter.default.publisher(for: UITextField.textDidBeginEditingNotification)) { obj in
                    if let textField = obj.object as? UITextField {
                        textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
                    }
                }

1
投票

代替这个:

TextField("", value: $amount, formatter: currencyFormat)
                .keyboardType(.numbersAndPunctuation)

使用这个:

TextField("",value: $amount, format: .currency(code: Locale.current.currency?.identifier ?? "USD"))

0
投票

这是对我有用的解决方法。它使用 FocusState 在两个格式化程序之间切换。

import SwiftUI

struct ContentView: View {
    @State private var amount: Double = 0

    var body: some View {
        HStack {
            Text("Enter Amount")
            Spacer()
            CurrencyTextField(title: "", value: $amount)
        }
        .padding()
    }
}

struct CurrencyTextField: View {

    var title: String
    @Binding var value: Double
    
    @FocusState private var isFocused: Bool

    private let currencyNumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency

        return formatter
    }()

    private let decimalNumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.usesGroupingSeparator = false

        return formatter
    }()

    var body: some View {
        TextField(title, value: $value, formatter: isFocused ? decimalNumberFormatter : currencyNumberFormatter)
            .keyboardType(.decimalPad)
            .focused($isFocused)
    }
}

#Preview {
    ContentView()
}
© www.soinside.com 2019 - 2024. All rights reserved.