मुद्रा के लिए स्विफ्ट में NSNumberFormatter के साथ संघर्ष


86

मैं एक बजट ऐप बना रहा हूं जो उपयोगकर्ता को अपने बजट के साथ-साथ लेनदेन करने की अनुमति देता है। मुझे उपयोगकर्ता को अलग-अलग पाठ क्षेत्रों से पेंस और पाउंड दोनों में प्रवेश करने की अनुमति देने की आवश्यकता है और उन्हें मुद्रा प्रतीकों के साथ प्रारूपित करने की आवश्यकता है। मेरे पास इस समय यह ठीक है लेकिन मैं इसे स्थानीयकृत बनाना चाहूंगा क्योंकि वर्तमान में यह केवल GBP के साथ काम करता है। मैं ऑब्जेक्टिव C से स्विफ्ट तक NSNumberFormatter उदाहरणों को गुप्त करने के लिए संघर्ष कर रहा हूं।

मेरा पहला मुद्दा यह तथ्य है कि मुझे इनपुट फ़ील्ड के लिए प्लेसहोल्डर को उपयोगकर्ता स्थान के लिए विशिष्ट होना चाहिए। उदाहरण के लिए। पाउंड और पेंस, डॉलर और सेंट आदि ...

दूसरा मुद्दा यह है कि प्रत्येक टेक्स्ट फ़ील्ड में दिए गए मान जैसे कि 10216 और 32 को फ़ॉर्मेट किया जाना चाहिए और उपयोगकर्ता स्थान के लिए विशिष्ट मुद्रा प्रतीक को जोड़ना होगा। तो यह £ 10,216.32 या $ 10,216.32 आदि बन जाएगा ...

इसके अलावा, मुझे एक गणना में स्वरूपित संख्या के परिणाम का उपयोग करने की आवश्यकता है। तो मैं मुद्रा प्रतीक के साथ मुद्दों में भागे बिना मुद्दों के बिना यह कैसे कर सकता हूं?

कोई भी सहायताकाफी प्रशंसनीय होगी।


2
क्या आप गैर-कार्यशील कोड का एक उदाहरण पोस्ट कर सकते हैं?
नाइनोस्क्रिप्ट

जवाबों:


205

इसका उपयोग स्विफ्ट 3 में कैसे किया जाए, इस पर एक उदाहरण है ( संपादित करें : स्विफ्ट 4 में भी काम करता है)

let price = 123.436 as NSNumber

let formatter = NumberFormatter()
formatter.numberStyle = .currency
// formatter.locale = NSLocale.currentLocale() // This is the default
// In Swift 4, this ^ has been renamed to simply NSLocale.current
formatter.string(from: price) // "$123.44"

formatter.locale = Locale(identifier: "es_CL")
formatter.string(from: price) // $123"

formatter.locale = Locale(identifier: "es_ES")
formatter.string(from: price) // "123,44 €"

यहां स्विफ्ट 2 पर इसका उपयोग करने का पुराना उदाहरण दिया गया है।

let price = 123.436

let formatter = NSNumberFormatter()
formatter.numberStyle = .CurrencyStyle
// formatter.locale = NSLocale.currentLocale() // This is the default
formatter.stringFromNumber(price) // "$123.44"

formatter.locale = NSLocale(localeIdentifier: "es_CL")
formatter.stringFromNumber(price) // $123"

formatter.locale = NSLocale(localeIdentifier: "es_ES")
formatter.stringFromNumber(price) // "123,44 €"

धन्यवाद। मैंने अपना प्रश्न संपादित किया है और अधिक विशिष्ट रहा है।
user3746428

आपके द्वारा दिए गए उदाहरण के आधार पर, मैंने अपने कार्यक्रम में संख्या स्वरूपण को लागू करने में कामयाबी हासिल की है, ताकि बिट को क्रमबद्ध किया जा सके। अब मुझे केवल यह पता लगाना है कि उपयोगकर्ताओं के स्थान के आधार पर टेक्स्ट फ़ील्ड प्लेसहोल्डर्स को कैसे सेट किया जाए।
user3746428

2
इसे NSNumber में डालने की कोई आवश्यकता नहीं है आप फ़ॉर्मेटर विधि का उपयोग कर सकते हैं func string (obj: Any के लिए?) -> स्ट्रिंग ?. इसलिए आपको string(for: price)इसके बजाय उपयोग करने की आवश्यकता हैstring(from: price)
सिंह Dabus

1
@LeoDabus आप सही हैं, मुझे उस पद्धति के बारे में पता नहीं था, मुझे यकीन नहीं है कि मुझे अपना उत्तर संपादित करना चाहिए, जैसा कि मुझे लगता है कि मैं नंबरफार्मेटर्स एपीआई का उपयोग करूँगा और स्पष्ट रूप से बताने के बजाय एनएसएनम्बर का उपयोग करने के बारे में स्पष्ट होना चाहिए। अंदर डाल दो।
नाइनोस्क्रिप्ट

ध्यान दें कि formatter.string (से :) का परिणाम एक वैकल्पिक स्ट्रिंग है न कि एक स्ट्रिंग (जैसा कि टिप्पणियों से निहित है) इसलिए उपयोग करने से पहले उन्हें अलग करना होगा।
अली बीडल

25

स्विफ्ट 3:

यदि आप एक समाधान की तलाश कर रहे हैं जो आपको देता है:

  • "5" = "$ 5"
  • "5.0" = "$ 5"
  • "5.00" = "$ 5"
  • "5.5" = "$ 5.50"
  • "5.50" = "$ 5.50"
  • "5.55" = "$ 5.55"
  • "5.234234" = "5.23"

कृपया निम्नलिखित का उपयोग करें:

func cleanDollars(_ value: String?) -> String {
    guard value != nil else { return "$0.00" }
    let doubleValue = Double(value!) ?? 0.0
    let formatter = NumberFormatter()
    formatter.currencyCode = "USD"
    formatter.currencySymbol = "$"
    formatter.minimumFractionDigits = (value!.contains(".00")) ? 0 : 2
    formatter.maximumFractionDigits = 2
    formatter.numberStyle = .currencyAccounting
    return formatter.string(from: NSNumber(value: doubleValue)) ?? "$\(doubleValue)"
}

एक नई NSNumber ऑब्जेक्ट को आरंभीकृत करने की आवश्यकता नहीं है जिसके func string(for obj: Any?) -> String?बजाय आप फ़ॉर्मेटर विधि का उपयोग कर सकते हैंstring(from:)
लियो डबस

19

मैंने @ NiñoScript द्वारा प्रदान किए गए समाधान को एक विस्तार के रूप में लागू किया है:

एक्सटेंशन

// Create a string with currency formatting based on the device locale
//
extension Float {
    var asLocaleCurrency:String {
        var formatter = NSNumberFormatter()
        formatter.numberStyle = .CurrencyStyle
        formatter.locale = NSLocale.currentLocale()
        return formatter.stringFromNumber(self)!
    }
}

उपयोग:

let amount = 100.07
let amountString = amount.asLocaleCurrency
print(amount.asLocaleCurrency())
// prints: "$100.07"

स्विफ्ट 3

    extension Float {
    var asLocaleCurrency:String {
        var formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.locale = Locale.current
        return formatter.string(from: self)!
    }
}

विस्तार स्विफ्ट 3 संस्करण और स्ट्रिंग के लिए फ़्लोटिंगपॉइंट का विस्तार किया जाना चाहिए (एनएसएनम्बर के लिए) विधि: फ़्लोटिंगप्वाइंट के प्रकारों के लिए आपको स्ट्रिंग का उपयोग करने की आवश्यकता है (:) विधि के लिए। मैंने एक स्विफ्ट 3 एक्सटेंशन पोस्ट किया है
लियो डबस

मुद्रा के लिए फ्लोट प्रकारों का उपयोग न करें, दशमलव का उपयोग करें।
अडंको

17

Xcode 11 • स्विफ्ट 5.1

extension Locale {
    static let br = Locale(identifier: "pt_BR")
    static let us = Locale(identifier: "en_US")
    static let uk = Locale(identifier: "en_GB") // ISO Locale
}

extension NumberFormatter {
    convenience init(style: Style, locale: Locale = .current) {
        self.init()
        self.locale = locale
        numberStyle = style
    }
}

extension Formatter {
    static let currency = NumberFormatter(style: .currency)
    static let currencyUS = NumberFormatter(style: .currency, locale: .us)
    static let currencyBR = NumberFormatter(style: .currency, locale: .br)
}

extension Numeric {
    var currency: String { Formatter.currency.string(for: self) ?? "" }
    var currencyUS: String { Formatter.currencyUS.string(for: self) ?? "" }
    var currencyBR: String { Formatter.currencyBR.string(for: self) ?? "" }
}

let price = 1.99

print(Formatter.currency.locale)  // "en_US (current)\n"
print(price.currency)             // "$1.99\n"

Formatter.currency.locale = .br
print(price.currency)  // "R$1,99\n"

Formatter.currency.locale = .uk
print(price.currency)  // "£1.99\n"

print(price.currencyBR)  // "R$1,99\n"
print(price.currencyUS)  // "$1.99\n"

3
मुद्रा के लिए फ्लोट प्रकारों का उपयोग न करें, दशमलव का उपयोग करें।
एडनाको


7

विवरण

  • Xcode 10.2.1 (10E1001), स्विफ्ट 5

समाधान

import Foundation

class CurrencyFormatter {
    static var outputFormatter = CurrencyFormatter.create()
    class func create(locale: Locale = Locale.current,
                      groupingSeparator: String? = nil,
                      decimalSeparator: String? = nil,
                      style: NumberFormatter.Style = NumberFormatter.Style.currency) -> NumberFormatter {
        let outputFormatter = NumberFormatter()
        outputFormatter.locale = locale
        outputFormatter.decimalSeparator = decimalSeparator ?? locale.decimalSeparator
        outputFormatter.groupingSeparator = groupingSeparator ?? locale.groupingSeparator
        outputFormatter.numberStyle = style
        return outputFormatter
    }
}

extension Numeric {
    func toCurrency(formatter: NumberFormatter = CurrencyFormatter.outputFormatter) -> String? {
        guard let num = self as? NSNumber else { return nil }
        var formatedSting = formatter.string(from: num)
        guard let locale = formatter.locale else { return formatedSting }
        if let separator = formatter.groupingSeparator, let localeValue = locale.groupingSeparator {
            formatedSting = formatedSting?.replacingOccurrences(of: localeValue, with: separator)
        }
        if let separator = formatter.decimalSeparator, let localeValue = locale.decimalSeparator {
            formatedSting = formatedSting?.replacingOccurrences(of: localeValue, with: separator)
        }
        return formatedSting
    }
}

प्रयोग

let price = 12423.42
print(price.toCurrency() ?? "")

CurrencyFormatter.outputFormatter = CurrencyFormatter.create(style: .currencyISOCode)
print(price.toCurrency() ?? "nil")

CurrencyFormatter.outputFormatter = CurrencyFormatter.create(locale: Locale(identifier: "es_ES"))
print(price.toCurrency() ?? "nil")

CurrencyFormatter.outputFormatter = CurrencyFormatter.create(locale: Locale(identifier: "de_DE"), groupingSeparator: " ", style: .currencyISOCode)
print(price.toCurrency() ?? "nil")

CurrencyFormatter.outputFormatter = CurrencyFormatter.create(groupingSeparator: "_", decimalSeparator: ".", style: .currencyPlural)
print(price.toCurrency() ?? "nil")

let formatter = CurrencyFormatter.create(locale: Locale(identifier: "de_DE"), groupingSeparator: " ", decimalSeparator: ",", style: .currencyPlural)
print(price.toCurrency(formatter: formatter) ?? "nil")

परिणाम

$12,423.42
USD12,423.42
12.423,42 €
12 423,42 EUR
12_423.42 US dollars
12 423,42 Euro

3

स्विफ्ट 4 के लिए @Michael Voccola के जवाब से अपडेट:

extension Double {
    var asLocaleCurrency: String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.locale = Locale.current

        let formattedString = formatter.string(from: self as NSNumber)
        return formattedString ?? ""
    }
}

नोट: कोई बल-अलिखित, बल-अलंकार अनिष्टकारी नहीं हैं।


2

स्विफ्ट 4 टेक्स्टफिल्ड लागू

var value = 0    
currencyTextField.delegate = self

func numberFormatting(money: Int) -> String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.locale = .current
        return formatter.string(from: money as NSNumber)!
    }

currencyTextField.text = formatter.string(from: 50 as NSNumber)!

func textFieldDidEndEditing(_ textField: UITextField) {
    value = textField.text
    textField.text = numberFormatting(money: Int(textField.text!) ?? 0 as! Int)
}

func textFieldDidBeginEditing(_ textField: UITextField) {
    textField.text = value
}

0
extension Float {
    var convertAsLocaleCurrency :String {
        var formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.locale = Locale.current
        return formatter.string(from: self as NSNumber)!
    }
}

यह तेजी से 3.1 xcode 8.2.1 के लिए काम कर रहा है


जबकि इस कोड स्निपेट का स्वागत है, और कुछ मदद प्रदान कर सकता है, यह हो जाएगा काफी सुधार हुआ है, तो यह उसका स्पष्टीकरण शामिल की कैसे और क्यों इस को हल करती है समस्या। याद रखें कि आप भविष्य में पाठकों के लिए सवाल का जवाब दे रहे हैं, न कि केवल उस व्यक्ति से जो अब पूछ रहा है! कृपया स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें, और इस बात का संकेत दें कि क्या सीमाएँ और मान्यताएँ लागू होती हैं।
टोबी स्पाइट

मुद्रा के लिए फ्लोट प्रकारों का उपयोग न करें, दशमलव का उपयोग करें।
एडनाको

0

स्विफ्ट 4

formatter.locale = Locale.current

यदि आप स्थान बदलना चाहते हैं तो आप इसे इस तरह से कर सकते हैं

formatter.locale = Locale.init(identifier: "id-ID") 

// यह इंडोनेशिया लोकेल के लिए लोकल है। यदि आप मोबाइल फोन क्षेत्र के अनुसार उपयोग करना चाहते हैं तो इसे ऊपरी उल्लेख Locale.current के अनुसार उपयोग करें

//MARK:- Complete code
let formatter = NumberFormatter()
formatter.numberStyle = .currency
    if let formattedTipAmount = formatter.string(from: Int(newString)! as 
NSNumber) { 
       yourtextfield.text = formattedTipAmount
}

0

इस फ़ंक्शन को जोड़ें

func addSeparateMarkForNumber(int: Int) -> String {
var string = ""
let formatter = NumberFormatter()
formatter.locale = Locale.current
formatter.numberStyle = .decimal
if let formattedTipAmount = formatter.string(from: int as NSNumber) {
    string = formattedTipAmount
}
return string
}

का उपयोग करते हुए:

let giaTri = value as! Int
myGuessTotalCorrect = addSeparateMarkForNumber(int: giaTri)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.