Форматирование чисел в Swift 3

Я хочу отформатировать число к этому: 123.234.234.234 от 123234234234 зависит от того, что пользователь вводит в текстовое поле. Я не хочу управлять валютой, речь идет не о валюте, а о том, что пользователь должен ввести число, и этот номер должен быть правильно отформатирован, чтобы его было легче читать.

Не с запятой, с точкой.

Я нашел только валюту во всем исследовании

5 ответов

То, что вы ищете, вероятно, groupingSeparator из NumberFormatter

let formater = NumberFormatter()
formater.groupingSeparator = "."
formater.numberStyle = .decimal
let formattedNumber = formater.string(from: number)

На самом деле есть гораздо более простое решение (нет необходимости создавать NumberFormatter instance) и учитывает язык пользователя:

let result = String(format: "%ld %@", locale: Locale.current, viewCount, "views")

Результат для значения 1000000 с английским языком:

1,000,000

Русский:

1 000 000

ps в Android точно так же String.format(Locale.getDefault(), "%,d %s", viewCount, "views")

Вы можете сделать это с NumberFormatter:

let yourNumber = 123234234234 
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = NumberFormatter.Style.decimal
numberFormatter.groupingSeparator = "."
let formattedNumber = numberFormatter.string(from: NSNumber(value:yourNumber))

подробности

xCode 9.2, Swift 4

Решение

import Foundation

extension String {
    var toLocale: Locale {
        return Locale(identifier: self)
    }
}

extension Numeric {

    func format(numberStyle: NumberFormatter.Style = NumberFormatter.Style.decimal, locale: Locale = Locale.current) -> String? {
        if let num = self as? NSNumber {
            let formater = NumberFormatter()
            formater.numberStyle = numberStyle
            formater.locale = locale
            return formater.string(from: num)
        }
        return nil
    }

    func format(numberStyle: NumberFormatter.Style = NumberFormatter.Style.decimal, groupingSeparator: String = ".", decimalSeparator: String = ",") -> String? {
        if let num = self as? NSNumber {
            let formater = NumberFormatter()
            formater.numberStyle = numberStyle
            formater.groupingSeparator = groupingSeparator
            formater.decimalSeparator = decimalSeparator
            return formater.string(from: num)
        }
        return nil
    }
}

использование

value.format()
value.format(locale: "fr_FR".toLocale)
value.format(numberStyle: .currency, locale: "de_DE".toLocale)
value.format(groupingSeparator: "_", decimalSeparator: ",")

Полный образец

Не забудьте добавить код решения здесь

func test<T: Numeric>(value: T) {
    print("=========================================================")
    print("\(T.self), value = \(value)")

    print(title: "value.format() = ", value: value.format())
    print(title: "value.format(locale: \"fr_FR\".toLocale) = ", value: value.format(locale: "fr_FR".toLocale))
    print(title: "value.format(numberStyle: .currency, locale: \"de_DE\".toLocale) = ", value: value.format(numberStyle: .currency, locale: "de_DE".toLocale))

    print(title: "value.format(groupingSeparator: \" \", decimalSeparator: \",\") = ", value: value.format(groupingSeparator: "_", decimalSeparator: ","))
}

func print(title: String, value: String?) {
    if let value = value {
        print("\(title) \(value)")
    }
}

test(value: Int(10000))
test(value: Double(10000.231))
test(value: Float(10000.231))

Результат

Свифт 4

extension Int {
    func formatnumber() -> String {
        let formater = NumberFormatter()
        formater.groupingSeparator = "."
        formater.numberStyle = .decimal
        return formater.string(from: NSNumber(value: self))!
    }
}

Для ведущих нулей (Swift 5.2)

String(format: "%02d", intNumber) // 6 -> "06"
String(format: "%03d", intNumber) // 66 -> "066"
String(format: "%04d", intNumber) // 666 -> "0666"

из: /questions/18759510/veduschie-nuli-dlya-int-v-swift/18759527#18759527

Для swift 4 я реализовал расширение, в котором я могу выбрать форматирование или использовать формат по умолчанию, если ни один не выбран.

extension Int {
    func formatnumber(groupingSeparator: String?) -> String {
        let formater = NumberFormatter()
        formater.groupingSeparator = (groupingSeparator != nil) ? groupingSeparator! : ","
        formater.numberStyle = .decimal
        return formater.string(from: NSNumber(value: self))!
    }
}

Мой скрипт в качестве примера:

1) Добавить расширение в проект

extension String {

    public func subString(startIndex: String.Index, endIndex: String.Index) -> String {
        return String(self[startIndex...endIndex])
    }

    public func subString(_ from: Int, _ to: Int) -> String {
          let startIndex = self.index(self.startIndex, offsetBy: from)
          let endIndex = self.index(self.startIndex, offsetBy: to)
        return String(self[startIndex...endIndex])
    }
}

2) Создайте файл Utilites.swift и добавьте мой метод

public func  priceNumFormat(_ number: String)->String{

    var formattedNumber = number
    var print = number
    var prefix = ""

    if number.range(of:"-") != nil {
        let index = number.index(of:"-")
        formattedNumber.remove(at: index ?? formattedNumber.endIndex)
        prefix = "-"
    }


    if formattedNumber.range(of:".") != nil {
        let index = formattedNumber.index(of:".")
        formattedNumber =  formattedNumber.subString(startIndex: formattedNumber.startIndex, endIndex: index ?? formattedNumber.endIndex)
        formattedNumber.remove(at: index ?? formattedNumber.endIndex)
    }

    if formattedNumber.count == 8 //10 000 000
    {
       let num0 = formattedNumber.subString(0, 1)
       let num1 = formattedNumber.subString(2, 4)
       let num2 = formattedNumber.subString(5, 7)
       print =  "\(num0) \(num1) \(num2)"
    }

    if formattedNumber.count == 7 //1 000 000
    {
        let num0 = formattedNumber.subString(0, 0)
        let num1 = formattedNumber.subString(1, 3)
        let num2 = formattedNumber.subString(4, 6)
        print =  "\(num0) \(num1) \(num2)"
    }

    if formattedNumber.count == 6 //100 000
    {
        let num0 = formattedNumber.subString(0, 2)
        let num1 = formattedNumber.subString(3, 5)
        print =  "\(num0) \(num1)"
    }

    if formattedNumber.count == 5 //10 000
    {
        let num0 = formattedNumber.subString(0, 1)
        let num1 = formattedNumber.subString(2, 4)
        print =  "\(num0) \(num1)"
    }

    if formattedNumber.count == 4 //1 000
    {
        let num0 = formattedNumber.subString(0, 0)
        let num1 = formattedNumber.subString(1, 3)
        print =  "\(num0) \(num1)"
    }

    if formattedNumber.count == 3 //100
    {
        print =  formattedNumber
    }

    if prefix.count > 0
    {
        print = "- \(print)"
    }

    return print;
}

3) Добавьте код в свой UIController

 let utils = Utilites()
            private func test(){
                var price =  self.utils.priceNumFormat("-12345678.000")
                print("\(price)") //-12 345 678
                price =  self.utils.priceNumFormat("-1234567.000")
                print("\(price)") //-1 234 567
                price =  self.utils.priceNumFormat("-123456.000")
                print("\(price)") //-123 456
                price =  self.utils.priceNumFormat("-12345.000")
                print("\(price)") //-12 345
                price =  self.utils.priceNumFormat("-1234.000")
                print("\(price)") //-1 234
                price =  self.utils.priceNumFormat("-123.000")
                print("\(price)") //-123

            }
Другие вопросы по тегам