Adding comma separator with NSNumber formatter [duplicate] - ios

I'm new to code and after reviewing a few answers still need a hand with this.
In my code:
func labelInformation(){
numLabels.text = newLabel.text
}
Current result:
228500.23
Desired result:
228,500.23
How/where do I use NSNumberFormatter?

Try like this:
let inputValue = 228500.23
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .CurrencyStyle
numberFormatter.currencySymbol = ""
let outputString = numberFormatter.stringFromNumber(inputValue) ?? "0.00"
print(outputString) // 228,500.23

Related

Dynamically using specific variables with custom UITableViewCell

This question will be a follow-up of this previous one.
I'm at the point where the user can create UITableViewCells and enter an amount to a TextField. It is then printed to a label and should update a variable that will be used with another variable for a calculation (basically amount * currentPrice, this is a wallet).
I re-read Apple's doc about TableViews and re-opened the exercises I did when I followed the Swift course but I'm struggling to understand the principle here, so once again, I think I really need someone to explain differently than what I could read so my brain can understand.
How will the cell know what variable to use here:
Entering the amount:
func cellAmountEntered(_ walletTableViewCell: WalletTableViewCell) {
if walletTableViewCell.amountTextField.text == "" {
return
}
let str = walletTableViewCell.amountTextField.text
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "en_US")
let dNumber = formatter.number(from: str!)
let nDouble = dNumber!
let eNumber = Double(truncating: nDouble)
walletTableViewCell.amountLabel.text = String(format:"%.8f", eNumber)
UserDefaults.standard.set(walletTableViewCell.amountLabel.text, forKey: "cellAmount")
walletTableViewCell.amountTextField.text = ""
}
Calculations and display:
func updateCellValueLabel(cryptoPrice: String) {
if walletTableViewCell.amountLabel.text == "" {
walletTableViewCell.amountLabel.text = "0.00000000"
}
let formatter1 = NumberFormatter()
formatter1.locale = Locale(identifier: "en_US")
let str = walletTableViewCell.amountLabel.text
let dNumber = formatter1.number(from: str!)
let nDouble = dNumber!
let eNumber = Double(truncating: nDouble)
UserDefaults.standard.set(eNumber, forKey: "currentAmount")
guard let cryptoDoublePrice = CryptoInfo.cryptoPriceDic[cryptoPrice] else { return }
WalletViewController.bitcoinAmountValue = cryptoDoublePrice * eNumber
if WalletViewController.currencyCode != "" {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "\(WalletViewController.currencyCode)")
walletTableViewCell.cryptoValueLabel.text = formatter.string(from: NSNumber(value: WalletViewController.amountValue))
}
UserDefaults.standard.set(WalletViewController.walletDoubleValue, forKey: "walletValue")
}
What I can't process here is how can I save the amount entered to the corresponding crypto UserDefaults file, then load this amount to be used with the corresponding variable that has the current price for calculations.
I don't know how to use the correct data for the correct cell.
Should I make this a single function? Should I pass parameters to the function (how do I pass the correct parameters to the corresponding cell with delegate?)? Do I need an array of parameters that will be used at indexPath to the correct cell (but how do I know the order if the user creates cells at will?)?
I'm kind of lost here.

The NSFormatter for Converting English Number to persian or arabic Number in Swift 3

I read the similar questions here and Write this method in my app
let formatter = NumberFormatter()
func convertEngNumToPersianNum(num: String)->String{
let number = NSNumber(value: Int(num)!)
let format = NumberFormatter()
format.locale = Locale(identifier: "fa_IR")
let faNumber = format.string(from: number)
return faNumber!
}
I didn't get Error But I didn't get the result too!
my Number code is this :
let checkNumber = Home2ViewController().customtitle.count
personalCustom.text = ("\(checkNumber)")
I used another Number in another View Controller that works But I want to show this Number in persian or arabic number format not in English format
Try this :
func convertEngNumToPersianNum(num: String)->String{
//let number = NSNumber(value: Int(num)!)
let format = NumberFormatter()
format.locale = Locale(identifier: "fa_IR")
let number = format.number(from: num)
let faNumber = format.string(from: number!)
return faNumber!
}
OR repalce with your line
let number = format.number(from: num)
let faNumber = format.string(from: number!)
You can do something like,
let formatter = NumberFormatter()
formatter.locale = NSLocale.current // you can specify locale that you want
formatter.numberStyle = .decimal
formatter.usesGroupingSeparator = true
let number = formatter.number(from: "١٠.٠٠")
print(number ?? "")
To convert to Arabic while keeping the leading zeros
func convertToArDigits(_ digits: String) -> String {
// We need a CFMutableString and a CFRange:
let cfstr = NSMutableString(string: digits) as CFMutableString
var range = CFRange(location: 0, length: CFStringGetLength(cfstr))
// Do the transliteration (this mutates `cfstr`):
CFStringTransform(cfstr, &range, kCFStringTransformLatinArabic, false)
// Convert result back to a Swift string:
return (cfstr as String)
}
extension String {
public var faToEnDigits : String {
let farsiNumbers = ["٠": "0","١": "1","٢": "2","٣": "3","٤": "4","٥": "5","٦": "6","٧": "7","٨": "8","٩": "9"]
var txt = self
farsiNumbers.map { txt = txt.replacingOccurrences(of: $0, with: $1)}
return txt
}
public var enToFaDigits : String {
let englishNumbers = ["0": "۰","1": "۱","2": "۲","3": "۳","4": "۴","5": "۵","6": "۶","7": "۷","8": "۸","9": "۹"]
var txt = self
englishNumbers.map { txt = txt.replacingOccurrences(of: $0, with: $1)}
return txt
}
}

How/where do I use NSNumberFormatter?

I'm new to code and after reviewing a few answers still need a hand with this.
In my code:
func labelInformation(){
numLabels.text = newLabel.text
}
Current result:
228500.23
Desired result:
228,500.23
How/where do I use NSNumberFormatter?
Try like this:
let inputValue = 228500.23
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .CurrencyStyle
numberFormatter.currencySymbol = ""
let outputString = numberFormatter.stringFromNumber(inputValue) ?? "0.00"
print(outputString) // 228,500.23

Convert Double to Scientific Notation in swift

I am trying to convert a given double into scientific notation, and running into some problems. I cant seem to find much documentation on how to do it either. Currently I am using:
var val = 500
var numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.ScientificStyle
let number = numberFormatter.numberFromString("\(val)")
println(number as Double?)
// Prints optional(500) instead of optional(5e+2)
What am I doing wrong?
You can set NumberFormatter properties positiveFormat and exponent Symbol to format your string as you want as follow:
let val = 500
let formatter = NumberFormatter()
formatter.numberStyle = .scientific
formatter.positiveFormat = "0.###E+0"
formatter.exponentSymbol = "e"
if let scientificFormatted = formatter.string(for: val) {
print(scientificFormatted) // "5e+2"
}
update: Xcode 9 • Swift 4
You can also create an extension to get a scientific formatted description from Numeric types as follow:
extension Formatter {
static let scientific: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .scientific
formatter.positiveFormat = "0.###E+0"
formatter.exponentSymbol = "e"
return formatter
}()
}
extension Numeric {
var scientificFormatted: String {
return Formatter.scientific.string(for: self) ?? ""
}
}
print(500.scientificFormatted) // "5e+2"
The issue is that you are printing the number... not the formatted number. You are calling numberForString instead of stringForNumber
var val = 500
var numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.ScientificStyle
let numberString = numberFormatter.stringFromNumber(val)
println(numberString)
Slight modification to the answer by leo-dabus to Xcode 9 Swift 4:
extension Double {
struct Number {
static var formatter = NumberFormatter()
}
var scientificStyle: String {
Number.formatter.numberStyle = .scientific
Number.formatter.positiveFormat = "0.###E+0"
Number.formatter.exponentSymbol = "e"
let number = NSNumber(value: self)
return Number.formatter.string(from :number) ?? description
}
}

Format Int64 with thousand separators

I have used below code successfully to format Int with thousand separators. However my current project required Int64 to be formatted the same way and it throws error 'Int64' is not convertible to 'NSNumber'
var numberFormatter: NSNumberFormatter {
let formattedNumber = NSNumberFormatter()
formattedNumber.numberStyle = .DecimalStyle
formattedNumber.maximumFractionDigits = 0
return formattedNumber
}
You mean when you call numberFormatter.stringFromNumber(12345678) after the above code, like this?
let i64: Int64 = 1234567890
numberFormatter.stringFromNumber(i64)
Doesn’t look like Swift will cast from an Int64 to an NSNumber:
let i = 1234567890
let n = i as NSNumber // OK
numberFormatter.stringFromNumber(i) // Also OK
// Compiler error: 'Int64' is not convertible to 'NSNumber'
let n64 = i64 as NSNumber
// so the implicit conversion will also fail:
numberFormatter.stringFromNumber(i64)
This is a bit confounding, since Swift Ints are themselves usually the same size as Int64s.
You can work around it by constructing an NSNumber by hand:
let n64 = NSNumber(longLong: i64)
BTW beware that var trick: it’s nice that it encapsulates all the relevant code for creating numberFormatter, but that code will run afresh every time you use it. As an alternative you could do this:
let numberFormatter: NSNumberFormatter = {
let formattedNumber = NSNumberFormatter()
formattedNumber.numberStyle = .DecimalStyle
formattedNumber.maximumFractionDigits = 0
return formattedNumber
}()
If it’s a property in a struct/class, you could also make it a lazy var which has the added benefit of only being running if the variable is used, like your var, but only once.
struct Thing {
lazy var numberFormatter: NSNumberFormatter = {
println("blah")
let formattedNumber = NSNumberFormatter()
formattedNumber.numberStyle = .DecimalStyle
formattedNumber.maximumFractionDigits = 0
return formattedNumber
}()
}
extension Formatter {
static let decimalNumber: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter
}()
}
extension Numeric {
var formatted: String { Formatter.decimalNumber.string(for: self) ?? "" }
}
let x: Int64 = 1000000
x.formatted // "1,000,000"

Resources