How to print formatted Decimal value in Swift? [duplicate] - ios

This question already has answers here:
How to convert Decimal to String with two digits after separator?
(2 answers)
Closed 5 years ago.
How to print formatted Decimal value in Swift? NumberFormatter works only with NSNumber, but Decimal is a struct. String(format:) doesn't work either.

Decimal is bridged with NSDecimalNumber, which is a subclass of NSNumber so NSNumberFormatter can handle it
let decimal = Decimal(11.24)
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
let string = formatter.string(from: decimal as NSDecimalNumber)!

Related

iOS Charts custom labels: integer values on Bubble Chart

I want to show the values displayed inside the bubbles as whole number Ints. For example: instead of "22.0" I just want "22".
The answer here doesn't work with the new iOS Charts because it requires an IValueFormatter instead of a NumberFormatter:
let numberFormatter = NumberFormatter()
numberFormatter.generatesDecimalNumbers = false
chartData.setValueFormatter(numberFormatter)
Error Message:
Cannot convert value of type 'NumberFormatter' to expected argument type 'IValueFormatter?'
Is there any way to solve this problem?
With the new charts, you still use numberformatter and then just convert at the end. Reference the code below.
let format = NumberFormatter()
format.generatesDecimalNumbers = false
let formatter = DefaultValueFormatter(formatter: format)
chartData.leftAxis.valueFormatter = (formatter as? IAxisValueFormatter)
Hope this helps!

How can I convert String to Double without losing precision in swift [duplicate]

This question already has answers here:
Swift - How to convert String to Double
(30 answers)
Closed 7 years ago.
How do I convert a string to double or float without losing precision
ex.
let stringNumber = "12.00"
What you want to use is NSString(format:) for the visual format of your value.
Swiftstub sample
To always show 2 digits visually use this:
NSString(format: "%.2f", value)

Convert Unicode (e.g. 1f564) to Emoji in Swift [duplicate]

This question already has answers here:
Print unicode character from variable (swift)
(7 answers)
Closed 7 years ago.
How do you convert unicode emoji stored as a string (e.g. 1f564) to an emoji that could be placed on a UILabel?
let myString = "1f564"
I've seen the use of the escape character but I can't insert variables to replace the characters.
let flag = "\u{1f1e9}\u{1f1ea}"
Thanks
This works. I don't know if there is anything more direct:
let myStr = "1f564"
let str = String(UnicodeScalar(Int(myStr, radix: 16)!)!)

How to use numberFromString when UITextField has currency value in Swift

I have an 'amount' input field that takes a number value that I wish to display as a currency within the input field itself. This I seem to be able to do with no issues.
I then use this value in a calculation and output as a currency value. Again this works fine the first time as it initially sees it as a double and not currency.
My problem comes when I try and reuse the value in the 'amount' input field, as the value is being seen and no longer a double because of the currency symbol etc.
Any suggestions?
Edited below based on suggestions:
var formatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
var numberOfPlaces = 2.0
var multiplier = pow(10, numberOfPlaces)
var enteredAmount = formatter.numberFromString(finalAmount.text)?.doubleValue ?? 0.0
enteredAmountLabel.text = formatter.stringFromNumber(enteredAmount)
finalAmount.text = formatter.stringFromNumber(enteredAmount)
Using these amends the calculations work the first time anything is entered into the field. If you try a calculation when the field is populated it resets the field to $0.00
If I amend to:
formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
Everything works as expected but the amount input field no longer displays as currency.
I am trying to provide screenshots but I do not have enough reputation points.
Is this the line that gives you trouble?
var enteredAmount = NSNumberFormatter().numberFromString(finalAmount.text)!.doubleValue
It looks like you've got the right idea. You can use a number formatter to convert a value to a formatted string for display, or to convert a formatted string to a value.
I would expect that code to work.
Is that line giving you a compile error? An error at runtime? Not giving the value that it should?
EDIT:
#LeonardoSavioDabus pointed out the problem. That line should use the number formatter you created above:
var enteredAmount = formatter.numberFromString(finalAmount.text)!.doubleValue
And you really shouldn't use force unwrapping like that. You should use the nil coalescing operator:
var enteredAmount = formatter.numberFromString(finalAmount.text)?.doubleValue ?? 0.0
EDIT #2:
Here in the US, this code works perfectly in a playground:
import Foundation
var formatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
let moneyString = "$12.93"
var enteredAmount = formatter.numberFromString(moneyString)?.doubleValue ?? 0.0
enteredAmount += 0.07
var newString = formatter.stringFromNumber(enteredAmount)
(I stripped out all the locale stuff to make it simpler.)
EDIT #3:
Your locale code doesn't make sense to me.
for identifier in ["en_US" , "en_UK" , "en_US","fr_FR"] {
formatter.locale = NSLocale(localeIdentifier: identifier)
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
}//end of locale detection for currency and decimal formatting
That code looks like it loops through 3 different values of identifier and assigns 3 different locales to your formatter, and the same max/min digit counts (both 2). The way I read that code, it's going to assign first the US locale, then the UK local, then US English again, and then finally French from France. So at the end of the loop the locale will be set to "fr_FR". That's probably not what you want.

Decimal point in calculations as . or ,

If I use decimal pad for input of numbers the decimal changes depending of country and region format.
May be as a point "." or as a comma ","
And I do not have control over at which device the app is used.
If the region format uses a comma the calculation gets wrong. Putting in 5,6 is the the same as putting in only 5 some times and as 56 same times.
And that is even if I programmatically allow both . and , as input in a TextField.
How do I come around this without using the numbers an punctation pad and probably also have to give instructions to avoid input with comma ","
It is only input for numbers and decimal I need and the decimal pad is so much nicer.
You shoudld use a NSNumberFormatter for this, as this can be set to handle different locales.
Create a formatter:
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setLocale:[NSLocale currentLocale]];
Use it:
NSNumber *number = [numberFormatter numberFromString: string]; //string is the textfield.text
if the device's locale is set to a locale, where the decimal separator in a ,, the Number Keypad will use is and the formatter as-well. On those the grouping separator will be .
For the other locales it will be vice-versa.
NSNumberFormatter is very sophisticated, you should read its section in Data Formatter Guide, too. It also knows a lot of currency handling (displaying, not conversion), if your app does handle such.
You can use also the class method of NSNumberFormatter
NSString* formattedString = [NSNumberFormatter
localizedStringFromNumber:number
numberStyle:NSNumberFormatterCurrencyStyle];
Identify is local country uses comma for decimal point
var isUsesCommaForDecimal : Bool {
let nf = NumberFormatter()
nf.locale = Locale.current
let numberLocalized = nf.number(from: "23,34")
if numberLocalized != nil {
return true
} else {
return false
}
}
One way could be to check if the textField contains a ",".
If it contains, replace it with "." and do all arithmetic operations.
As anyways you will be reading all textFields and textViews as NSString object, you can manipulate the input value and transform it according to your need.
Also while showing the result replace "." with "," so that user feel comfortable according to there regional formats.

Resources