Search code examples
iosswiftaccessibilityvoiceovercurrency-formatting

Currency Plural swift doesn't allow configuration


I want to remove a dot (".") from a NumberFormatter, because an issue with VoiceOver that read 20.000 (dot is separator in spanish) as 20 instead of 20000.

In the following example you can test that only currencyPlural is the only NumberFormatter.Style that announce complete string for currency but ignore usesGroupingSeparator flag.

Example:

func formatTest(_ style:  NumberFormatter.Style, usesGroupingSeparator separator: Bool) -> String? {
    let formatter = NumberFormatter()
    formatter.locale = Locale(identifier: "es_CL")
    formatter.usesGroupingSeparator = separator
    formatter.numberStyle = style
    return formatter.string(from: NSNumber(value: 20000))
}


formatTest(.currency, usesGroupingSeparator: false) // "$20000"
formatTest(.currencyAccounting, usesGroupingSeparator: false) // "$20000"
formatTest(.currencyISOCode, usesGroupingSeparator: false) // "CLP 20000"
formatTest(.currencyPlural, usesGroupingSeparator: false) // "20.000 pesos chilenos"

formatTest(.currency, usesGroupingSeparator: true) // "$20.000"
formatTest(.currencyAccounting, usesGroupingSeparator: true) // "$20.000"
formatTest(.currencyISOCode, usesGroupingSeparator: true) // "CLP 20.000"
formatTest(.currencyPlural, usesGroupingSeparator: true) // "20.000 pesos chilenos"

Any idea how to fix this? Please don't post a response like removing dot manually because I want to use format for multiple languages.

Extra: Voiceover in spanish ALWAYS announce $ as dollars so I need complete text.


Solution

  • I want to remove a dot (".") from a NumberFormatter, because an issue with VoiceOver that read 20.000 (dot is separator in spanish) as 20 instead of 20000 [...] Any idea how to fix this?

    Display the formatted number you want and make VoiceOver read out whatever you desire ⟹ you don't need to remove the dot that's on screen. 👍
    The problem is that VoiceOver can't perfectly read the currency while there's no problem with numbers.

    A solution to your problem may be to append the locale currency to the amount (just for VoiceOver 😓) as follows:

    @IBOutlet weak var myLabel: UILabel!
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
    
            // Your function is used to display the formatted text.
            myLabel.text = formatTest(.currencyPlural,
                                      usesGroupingSeparator: true)
    
            let locale = Locale(identifier: "es_CL")
    
            let formatter = NumberFormatter()
            formatter.locale = locale
            formatter.numberStyle = .spellOut
    
            // Define the a11y label to be specifically read out by VoiceOver.
            myLabel.accessibilityLabel = formatter.string(from: 20000)! + " " + locale.localizedString(forCurrencyCode: locale.currencyCode!)!
        }
    

    Even if I don't know a single word of spanish, I changed my device configuration to test it and, apparently, it works as expected. 😳

    Adapt this code snippet to your environment in order to keep your format for multiple languages and have an automatic VoiceOver configuration for your locale currencies. 😉