Search code examples
swiftswiftuisetter

How do you force Swift setter to trigger on initial value?


In the DecimalAmount function I can't get it to display the initial value of the amount. It shows 0.00 as the initial display even though the actual value is 22.22. Anyone know how to get around this issue?

import SwiftUI

struct ContentView: View
{
    @State var amount: Decimal = 22.22
    
    var body: some View
    {
        DecimalAmount(prompt: "Enter Value", value: $amount)
            .padding()
    }
}

struct DecimalAmount: View
{
    @State var prompt = ""
    @Binding var value: Decimal
    
    var body: some View
    {
        // How to get this to show the initial value of 22.22
        TextField(prompt, text: Binding(get: { value.decimal }, set: { value = Decimal(string: $0) ?? 0.0 }))
            .keyboardType(.decimalPad)
    }
}

extension Decimal
{
    var decimal: String
    {
        return String(format: "%3.2f", self as NSDecimalNumber)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Solution

  • Use another init that has a value: argument so that you can use the Binding directly and also can be formatted directly using a supplied format

    TextField("",
              value: $value,
              format: .number.precision(.fractionLength(2)))
    

    This init also has a prompt: argument and it works fine both with and without it. documentation