Подтвердить что ты не робот

Как форматировать Double to Currency - Swift 3

Я новичок в программировании Swift, и в Xcode 8.2 я создал простой калькулятор калькулятора, у меня есть мои расчеты, установленные в моем IBAction ниже. Но когда я на самом деле запускаю свое приложение и вводю сумму для вычисления (например, 23.45), она имеет более двух десятичных знаков. Как это сделать в .currency в этом случае?

@IBAction func calculateButtonTapped(_ sender: Any) {

    var tipPercentage: Double {

        if tipAmountSegmentedControl.selectedSegmentIndex == 0 {
            return 0.05
        } else if tipAmountSegmentedControl.selectedSegmentIndex == 1 {
            return 0.10
        } else {
            return 0.2
        }
    }

    let billAmount: Double? = Double(userInputTextField.text!)

    if let billAmount = billAmount {
        let tipAmount = billAmount * tipPercentage
        let totalBillAmount = billAmount + tipAmount

        tipAmountLabel.text = "Tip Amount: $\(tipAmount)"
        totalBillAmountLabel.text = "Total Bill Amount: $\(totalBillAmount)"
    }
}
4b9b3361

Ответ 1

Вы можете использовать этот инициализатор строки, если вы хотите заставить валюту $:

String(format: "Tip Amount: $%.02f", tipAmount)

Если вы хотите, чтобы он полностью зависел от настроек локали устройства, вы должны использовать NumberFormatter. Это будет учитывать количество десятичных знаков для валюты, а также правильное позиционирование символа валюты. Например. двойное значение 2.4 вернет "2,40 €" для локали es_ES и "¥ 2" для локали jp_JP.

let formatter = NumberFormatter()
formatter.locale = Locale.current // Change this to another locale if you want to force a specific locale, otherwise this is redundant as the current locale is the default already
formatter.numberStyle = .currency
if let formattedTipAmount = formatter.string(from: tipAmount as NSNumber) {
    tipAmountLabel.text = "Tip Amount: \(formattedTipAmount)"
}

Ответ 2

Лучший способ сделать это - создать NSNumberFormatter. (NumberFormatter в Swift 3.) Вы можете запросить валюту, и она настроит строку, чтобы следовать настройкам локализации пользователя, что полезно.

Если вы хотите форсировать строку в долларах США и центов в формате US, вы можете отформатировать ее следующим образом:

let amount: Double = 123.45

let amountString = String(format: "$%.02f", amount)

Ответ 3

В дополнение к NumberFormatter или String(format:), обсуждаемым другими, вы можете рассмотреть возможность использования Decimal или NSDecimalNumber и самостоятельно контролировать округление, тем самым избегая проблем с плавающей запятой. Если вы делаете простой калькулятор чаевых, это, вероятно, не обязательно. Но если вы делаете что-то вроде добавления подсказок в конце дня, если вы не округлите числа и/или не выполните свою математику с использованием десятичных чисел, вы можете ввести ошибки.

Итак, продолжайте и настройте свой форматтер:

let formatter: NumberFormatter = {
    let _formatter = NumberFormatter()
    _formatter.numberStyle = .decimal
    _formatter.minimumFractionDigits = 2
    _formatter.maximumFractionDigits = 2
    _formatter.generatesDecimalNumbers = true
    return _formatter
}()

а затем используйте десятичные числа:

let string = "2.03"
let tipRate = Decimal(sign: .plus, exponent: -3, significand: 125) // 12.5%
guard let billAmount = formatter.number(from: string) as? Decimal else { return }
let tip = (billAmount * tipRate).rounded(2)

guard let output = formatter.string(from: tip as NSDecimalNumber) else { return }
print("\(output)")

Где

extension Decimal {

    /// Round `Decimal` number to certain number of decimal places.
    ///
    /// - Parameters:
    ///   - scale: How many decimal places.
    ///   - roundingMode: How should number be rounded. Defaults to `.plain`.
    /// - Returns: The new rounded number.

    func rounded(_ scale: Int, roundingMode: RoundingMode = .plain) -> Decimal {
        var value = self
        var result: Decimal = 0
        NSDecimalRound(&result, &value, scale, roundingMode)
        return result
    }
}

Очевидно, что вы можете заменить все вышеупомянутые ссылки "2 десятичных разряда" с любым номером, подходящим для используемой валюты (или, возможно, использовать переменную для количества десятичных знаков).

Ответ 4

Как это сделать в Swift 4:

let myDouble = 9999.99
let currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
// localize to your grouping and decimal separator
currencyFormatter.locale = Locale.current

// We'll force unwrap with the !, if you've got defined data you may need more error checking

let priceString = currencyFormatter.string(from: NSNumber(value: myDouble))!
print(priceString) // Displays $9,999.99 in the US locale

Ответ 5

Вы можете создать расширение для строки или Int, я бы показал пример со строкой

extension String{
     func toCurrencyFormat() -> String {
        if let intValue = Int(self){
           let numberFormatter = NumberFormatter()
           numberFormatter.locale = Locale(identifier: "ig_NG")/* Using Nigeria Naira here or you can use Locale.current to get current locale, please change to your locale, link below to get all locale identifier.*/ 
           numberFormatter.numberStyle = NumberFormatter.Style.currency
           return numberFormatter.string(from: NSNumber(value: intValue)) ?? ""
      }
    return ""
  }
}

ссылка, чтобы получить весь идентификатор локали

Ответ 6

Вы можете конвертировать таким образом: этот func convert сохраняет для вас MaximumFractionDigits всякий раз, когда вы хотите сделать

static func df2so(_ price: Double) -> String{
        let numberFormatter = NumberFormatter()
        numberFormatter.groupingSeparator = ","
        numberFormatter.groupingSize = 3
        numberFormatter.usesGroupingSeparator = true
        numberFormatter.decimalSeparator = "."
        numberFormatter.numberStyle = .decimal
        numberFormatter.maximumFractionDigits = 2
        return numberFormatter.string(from: price as NSNumber)!
    } 

я создаю его в классе Model, затем при вызове вы можете принять его в другой класс, например

 print("InitData: result convert string " + Model.df2so(1008977.72))
//InitData: result convert string "1,008,977.72"

Ответ 7

extension Float {
    var localeCurrency: String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.locale = .current
        return formatter.string(from: self as NSNumber)!
    }
}
    amount = 200.02
    print("Amount Saved Value ",String(format:"%.2f", amountSaving. localeCurrency))

Для меня его возвращение 0,00! Смотрится на меня Расширение Идеально при доступе к нему возвращает 0.00! Зачем?

Ответ 8

Вот как:

    let currentLocale = Locale.current
    let currencySymbol = currentLocale.currencySymbol
    let outputString = "\(currencySymbol)\(String(format: "%.2f", totalBillAmount))"

1-я строка: вы получаете текущую локаль

Вторая строка: вы получаете валюту для этого языкового стандарта. ($, £ и т.д.)

3-я строка: использование инициализатора формата для усечения двух-двух знаков после запятой.