2017-01-09 75 views
15

Tôi mới sử dụng chương trình Swift và tôi đã tạo ứng dụng máy tính mẹo đơn giản trong Xcode 8.2, tôi có các tính toán được thiết lập trong số IBAction bên dưới. Nhưng khi tôi thực sự chạy ứng dụng của tôi và nhập một số tiền để tính toán (chẳng hạn như 23.45), nó xuất hiện với hơn 2 chữ số thập phân. Làm thế nào để định dạng nó thành .currency trong trường hợp này?Cách định dạng Dấu hai thành Đơn vị tiền tệ - Swift 3

@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)" 
    } 
} 

Trả lời

25

Bạn có thể sử dụng chuỗi khởi tạo này nếu bạn muốn để buộc các tệ đến $:

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

Nếu bạn muốn nó được hoàn toàn phụ thuộc vào các thiết lập miền địa phương của thiết bị, bạn nên sử dụng một NumberFormatter. Điều này sẽ tính đến số vị trí thập phân cho đơn vị tiền tệ cũng như định vị ký hiệu tiền tệ chính xác. Ví dụ. giá trị kép 2.4 sẽ trả về "2,40 €" cho ngôn ngữ es_ES và "¥ 2" cho miền địa phương 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)" 
} 
+0

FYI - không cần phải đặt 'locale' thành' Locale.current' của trình định dạng vì đó là mặc định. – rmaddy

+2

Vâng, tôi biết, tôi đã thêm một bình luận để nói rằng nó dư thừa. Muốn giữ nó trong đó để hiển thị nó có thể dễ dàng được thay đổi. –

+0

Đã làm việc rất tốt. –

7

Cách tốt nhất để làm điều này là tạo NSNumberFormatter. (NumberFormatter trong Swift 3.) Bạn có thể yêu cầu tiền tệ và nó sẽ thiết lập chuỗi để thực hiện theo các cài đặt nội địa hóa của người dùng, đó là hữu ích.

Nếu bạn muốn buộc một đô la và cent Mỹ định dạng chuỗi bạn có thể định dạng nó theo cách này:

let amount: Double = 123.45 

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

Đây là cách:

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

1 dòng: Bạn đang gặp hiện nay locale

Dòng thứ hai: Bạn nhận được tiền tệSymbol cho ngôn ngữ đó. ($, £, v.v.)

Dòng thứ ba: Sử dụng trình khởi tạo định dạng để cắt bớt từ 2 đến 2 chữ số thập phân.

+0

Không làm điều này. Sử dụng 'NumberFormatter'. Cách tiếp cận này có nhiều vấn đề dễ dàng tránh được bằng cách sử dụng 'NumberFormatter'. – rmaddy

6

Ngoài các NumberFormatter hay String(format:) thảo luận bởi những người khác, bạn có thể muốn xem xét sử dụng Decimal hoặc NSDecimalNumber và kiểm soát việc làm tròn chính mình, do đó tránh các vấn đề dấu chấm động. Nếu bạn đang làm một máy tính tip đơn giản, điều đó có lẽ không cần thiết. Nhưng nếu bạn đang làm một cái gì đó như thêm các lời khuyên vào cuối ngày, nếu bạn không làm tròn số và/hoặc làm toán học của bạn bằng cách sử dụng số thập phân, bạn có thể giới thiệu lỗi.

Vì vậy, đi trước và cấu hình định dạng của bạn:

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

và sau đó, sử dụng số thập phân:

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)") 

đâu

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 
    } 
} 

Rõ ràng, bạn có thể thay thế tất cả các bên trên Tham chiếu "2 chữ số thập phân" với bất kỳ số nào phù hợp với đơn vị tiền tệ bạn đang sử dụng (hoặc có thể là chúng tôi e một biến số vị trí thập phân).

+0

Tại sao không sử dụng kiểu tiền tệ cho 'SốFormatter'? Không phải tất cả các loại tiền tệ đều sử dụng 2 chữ số thập phân. – rmaddy

+1

Đúng, bạn có thể làm điều đó. Và bạn thậm chí có thể tra cứu số chữ số thập phân mà bạn nên làm tròn. Phải thừa nhận rằng, việc sử dụng '.currency' giới thiệu các vấn đề khác (ví dụ: phân tích cú pháp chuỗi trở nên bất ổn; nó giả định bạn không đi du lịch và giao dịch với một số đơn vị tiền tệ khác, v.v.). Tùy thuộc vào ứng dụng, đôi khi nó dễ dàng hơn để cho phép người dùng xác định vị trí thập phân và được thực hiện với nó. Bên cạnh đó, quan điểm của tôi không phải là định dạng, mà đúng hơn là cố vấn chung để tránh toán học dấu chấm động với tiền tệ. – Rob

+0

Cách tiếp cận khác đối với vấn đề làm tròn là nhân số tiền "đô la và xu" (hoặc euro hoặc shekels hoặc bất kỳ) lên 100 (hoặc bằng số đơn vị phân số trong toàn bộ đơn vị, đối với tiền tệ không có 100 xu). Sau đó, sử dụng toán học số nguyên và chỉ cần định dạng đầu ra theo cách thủ công để chèn dấu tách thập phân. Cách tiếp cận đó cũng tránh được lỗi dấu phẩy động. –

Các vấn đề liên quan