Swift NumberFormatter 给出编译器错误

Swift NumberFormatter is giving compiler errors

我正在尝试在 SwiftUI 视图中使用 NumberFormatter,但出现编译器错误。这是我的代码:

import Foundation
import SwiftUI

struct AccountCard: View {
    var netWorth: NetWorth
    
    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    let investmentTotalString = formatter.string(for: netWorth.investmentTotal)
    
    var body: some View {
        VStack {
            Text(netWorth.name)
            Text(String(format: "%.2f", netWorth.investmentTotal))
            Text(String(format: "%.2f", netWorth.cashBalance))
        }
    }
}

struct AccountCard_Previews: PreviewProvider {
    static var previews: some View {
        AccountCard(netWorth: netWorths[0])
    }
}

我做错了什么?

这里 XCode 显示错误:

SwiftUI 不允许在其设置中使用 formatter.numberStyle = .currency 等语句。有地方 在视图中,例如 init(),.onAppear{},当然还有任何自定义函数, 允许此类声明的地方。

要实现您想要的效果,您可以尝试这样的操作:

struct AccountCard: View {
    var netWorth: NetWorth
    
    let formatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        return formatter
    }()
    
    @State var investmentTotalString: String?
    
    var body: some View {
        VStack {
            Text(netWorth.name)
            Text(String(format: "%.2f", netWorth.investmentTotal))
            Text(String(format: "%.2f", netWorth.cashBalance))
        }
        .onAppear {
            investmentTotalString = formatter.string(for: netWorth.investmentTotal)
        }
    }
}

基于 workingdog 所写的内容,创建 NumberFormatter 是一项昂贵的操作,因此您应该将其创建为静态的,因此不必一直重新创建它。是否需要State也是值得怀疑的,你总是可以用getter.

声明它只是var
struct AccountCard: View {
    var netWorth: NetWorth
    
    static let formatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        return formatter
    }()
    
    var investmentTotalString: String {
         AccountCard.formatter.string(for: netWorth.investmentTotal)
    }
    
    var body: some View {
        VStack {
            Text(netWorth.name)
            Text(String(format: "%.2f", netWorth.investmentTotal))
            Text(String(format: "%.2f", netWorth.cashBalance))
        }
    }
}

我们不再自己格式化字符串,我们让 SwiftUI 为我们做。这样做的原因是,如果用户更改其区域设置,它可以更新屏幕上的标签。使用 UIKit,我们中的大多数人从不费心去听区域设置更改通知。

我们可以简单地告诉 SwiftUI 我们想要什么格式:

struct AccountCard: View {
    let netWorth: NetWorth
    
    var body: some View {
        VStack {
            Text(netWorth.name)
            Text(netWorth.investmentTotal, format: .currency(code: "USD"))
            Text(netWorth.cashBalance, format: .currency(code: "USD"))
        }
    }
}

或者我们可以将格式化对象传递给字符串插值:

let currencyFormatter: NumberFormatter = {
    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    return formatter
}()

struct AccountCard: View {
    let netWorth: NetWorth
    
    var body: some View {
      VStack {
          Text(netWorth.name)
          Text("$\(netWorth.investmentTotal, formatter: currencyFormatter)")
          Text("$\(netWorth.cashBalance, formatter: currencyFormatter)")
        }
    }
}