Currency formatter SwiftUI

huangapple go评论69阅读模式
英文:

Currency formatter SwiftUI

问题

I'll provide a translation of the code part you shared:

我试图在用户输入值时进行格式化文本字段。我已经有以下代码,但是我找不到在文本字段中执行此操作的方法。

struct ContentView: View {
    @State private var amount: String = ""
    @State private var formattedAmount: String = ""
 
    var body: some View {
        VStack {
            Text("Valor: \(formattedAmount)")
            
            TextField("Valor", text: $amount)
                .textFieldStyle(.roundedBorder)
                .padding()
                .keyboardType(.numberPad)
                .onChange(of: amount, perform: { value in
                    updateFormattedAmount()
                })
        }
    }

    private func updateFormattedAmount() {
        guard let number = Double(amount) else {
            formattedAmount = ""
            return
        }
        
        let formatter = currencyFormatter
        formattedAmount = formatter.string(from: NSNumber(value: number / 100)) ?? ""
    }

    private var currencyFormatter: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.currencyCode = "BRL"
        formatter.currencySymbol = "R$"
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2
        formatter.groupingSeparator = "."
        formatter.usesGroupingSeparator = true
        return formatter
    }
}

I've translated the Swift code while preserving the structure and functionality.

英文:

I'm trying to format as the user inputs a value into the textfield. I have the following code already but I couldn't find a way to do this into the textfield.

import SwiftUI

struct ContentView: View {
    @State private var amount: String = ""
    @State private var formattedAmount: String = ""
 
    var body: some View {
        VStack {
            Text("Valor: \(formattedAmount)")
            
            TextField("Valor", text: $amount)
                .textFieldStyle(.roundedBorder)
                .padding()
                .keyboardType(.numberPad)
                .onChange(of: amount, perform: { value in
                    updateFormattedAmount()
                })
        }
    }

    private func updateFormattedAmount() {
        guard let number = Double(amount) else {
            formattedAmount = ""
            return
        }
        
        let formatter = currencyFormatter
        formattedAmount = formatter.string(from: NSNumber(value: number / 100)) ?? ""
    }

    private var currencyFormatter: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.currencyCode = "BRL"
        formatter.currencySymbol = "R$"
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2
        formatter.groupingSeparator = "."
        formatter.usesGroupingSeparator = true
        return formatter
    }
}

This is what I have on the UI:

Currency formatter SwiftUI

I wish to display on the textfield what I've done with formattedAmount var.

答案1

得分: 1

I like to use TextField 的新 format: API,例如:

struct ContentView: View {
    @State var amount: Decimal = 0 // 金额一般使用 Decimal 类型
    @Environment(\.locale) private var locale // 如果用户更改货币,body 将被调用。

    var body: some View {
        TextField("金额", value: $amount, format: .currency(code: locale.currency?.identifier ?? "USD"))
    }
}

或者

struct Amount {
    var value: Decimal = 0
    let currencyCode = "USD"
}

struct ContentView: View {
    @State var amount = Amount()

    var body: some View {
        TextField("金额", value: $amount.value, format: .currency(code: amount.currencyCode))
    }
}
英文:

I like to use TextField's new format: API, e.g.

struct ContentView: View {
    @State var amount: Decimal = 0 // always use Decimal for money
    @Environment(\.locale) private var locale // body will be called if they change their currency.

    var body: some View {

        TextField("Amount", value: $amount, format: .currency(code: locale.currency?.identifier ?? "USD")                
            
    }
}

or


struct Amount {
    var value: Decimal = 0
    let currencyCode = "USD"
}

struct ContentView: View {
    @State var amount = Amount()

    var body: some View {
        TextField("Amount", value: $amount.value, format: .currency(code: amount.currencyCode)
    }
}

答案2

得分: 0

Change

@State private var amount: String = ""
TextField("Valor", text: $amount)

To

@State private var amount: Double = 0.0
TextField("Valor", value: $amount, formatter: currencyFormatter)

Then when the user "submits" it will change the field with all the formatter settings.

英文:

Change

@State private var amount: String = ""

TextField("Valor", text: $amount)

To

@State private var amount: Double = 0.0

TextField("Valor", value: $amount, formatter: currencyFormatter)

Then when the user "submits" it will change the field with all the formatter settings.

答案3

得分: 0

Yes, the above answer suggested by @lorem ipsum is correct, 但你要理解的主要问题是,当编辑文本字段时,只有在关闭键盘后才会反映这些更改。如果你想实现这一点,你需要为UITextFieldDelegate编写Coordinators,主要在UITextFieldshouldChangeCharacterIn API中。此外,你写的代码不需要那么多来实现相同的效果。你可以直接在TextField API上使用Formatter,就像下面的代码一样。请查看下面的代码。它将按照你想要的方式工作,但需要点击“完成”按钮。

struct ContentView: View {
    @State private var amount: Double = 0.0
    let currencyFormatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.currencyCode = "BRL"
        formatter.currencySymbol = "R$"
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 0
        formatter.usesGroupingSeparator = true
        return formatter
    }()
    
    var body: some View {
        VStack {
            Text("Valor: \(amount, specifier: "%.2f")")
            TextField("Valor", value: $amount, format: .currency(code: "BRL"))
                .textFieldStyle(.roundedBorder)
                .padding()
                .keyboardType(.numberPad)
        }
    }
}

再次强调,如果你不需要“完成”按钮,那么请查看这篇文章,它是与你的问题最相似的方法。

How to Use Currency Input in a UITextField. 希望对你有所帮助。

英文:

yes, the above answer suggested by @lorem ipsum is correct, But the main thing you have to understand is while editing Textfield can reflect those changes once you dismiss the keyboard. And if you want to achieve that you have to write Coordinators for UITextFieldDelegate mostly in shouldChangeCharacterIn API of UITextField. Also the code that you have written, you don't need to write that much to achieve the same. you can directly use Formatter on the TextField API like below code. Pls see the below code. It will work the way you want it, but tapping on done button.

struct ContentView: View {
    @State private var amount: Double = 0.0
    let currencyFormatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.currencyCode = "BRL"
        formatter.currencySymbol = "R$"
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 0
        formatter.usesGroupingSeparator = true
        return formatter
    }()
    
    var body: some View {
        VStack {
            Text("Valor: \(amount, specifier: "%.2f")")
            TextField("Valor", value: $amount, format: .currency(code: "BRL"))
                .textFieldStyle(.roundedBorder)
                .padding()
                .keyboardType(.numberPad)
        }
    }
}

Again if you don't need on done button, than review this article, it is the closest approach similar to your question.

How to Use Currency Input in a UITextField. Hope it helps.

huangapple
  • 本文由 发表于 2023年5月18日 05:50:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276428.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定