更改 Swift/ SwiftUI 中小数的字体大小

change the fontsize of the decimal number in Swift/ SwiftUI

所以我需要让小数位小于实际数字我将在下面告诉你我的意思。

这是我的代码:

import SwiftUI

struct BalanceDetailsView: View {
    //MARK: - PROPERTIES
    var balance: Float
    var balanceString: String {
        return balance.formattedWithSeparator
    }
    //MARK: - BODY
    var body: some View {
        VStack{
            HStack{
                    Text(balanceString)
                        .font(.custom(K.fonts.gilroyBold, size: 24))
                        .multilineTextAlignment(.center)
                        .padding(.top)
             
            }//:VSTACK
        }//:HSTACK
    }
}

struct BalanceDetailsView_Previews: PreviewProvider {
    static var previews: some View {
        BalanceDetailsView(balance: 43678)
            .previewLayout(.sizeThatFits)
    }
}



//Formatter extension i used to get this code
extension Formatter {
    static let withSeparator: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal

        // minimum decimal digit, eg: to display 2 as 2.00
        formatter.minimumFractionDigits = 2

        // maximum decimal digit, eg: to display 2.5021 as 2.50
        formatter.maximumFractionDigits = 2
        
        return formatter
    }()
}

extension Numeric {
    var formattedWithSeparator: String { Formatter.withSeparator.string(for: self) ?? "" }
}
Result I get Result I need

当您知道字符串的确切格式时,例如在本例中最小字符串长度为 4("0.00") ,您可以安全地使用 dropLastdropFirst.

我建议将 2 移动到 priceFractionDigits 常量以减少代码中常量的使用。

然后您可以使用字符串连接,它将 Text 按基线对齐。

struct BalanceText: View {
    var balance: Float
    var balanceString: String {
        return balance.formattedWithSeparator
    }
    
    var body: some View {
        Text(balanceString.dropLast(priceFractionDigits))
            .font(.system(size: 24))
            +
            Text(balanceString.dropFirst(balanceString.count - priceFractionDigits))
            .font(.system(size: 18))
    }
}

private let priceFractionDigits = 2

extension Formatter {
    static let withSeparator: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal

        // minimum decimal digit, eg: to display 2 as 2.00
        formatter.minimumFractionDigits = priceFractionDigits

        // maximum decimal digit, eg: to display 2.5021 as 2.50
        formatter.maximumFractionDigits = priceFractionDigits
        
        return formatter
    }()
}

用法

BalanceText(balance: balance)

您可以将 Text+ 运算符连接在一起。

我稍微改变了您使用 NumberFormatter 的方式,因此它被区域设置的正确十进制字符分开。

struct BalanceDetailsView: View {
    private let wholeNumberPart: String
    private let decimalNumberPart: String

    init(balance: Double) {
        (wholeNumberPart, decimalNumberPart) = balance.formattedSplittingBySeparator
    }

    var body: some View {
        Text(wholeNumberPart).font(.system(size: 24)) +
        Text(decimalNumberPart).font(.system(size: 16))
    }
}


extension Numeric {
    var formattedSplittingBySeparator: (whole: String, decimal: String) {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2
        let str = formatter.string(for: self) ?? "0\(formatter.decimalSeparator!)00"
        let split = str.components(separatedBy: formatter.decimalSeparator)
        let whole = (split.first ?? "0") + formatter.decimalSeparator
        let decimal = split.count == 2 ? split[1] : "00"
        return (whole: whole, decimal: decimal)
    }
}

用法:

BalanceDetailsView(balance: 43678)

结果:

您可以用小数分隔符拆分字符串并以零间距显示各部分 HStack

struct BalanceView : View {
    let balance : Float
    
    var body: some View {
        let components = balance
                        .formattedWithSeparator
                        .components(separatedBy: Formatter.withSeparator.decimalSeparator)
        HStack(alignment: .firstTextBaseline, spacing: 0) {
            Text(components[0])
            if components.count > 1 {
                Text(".")
                Text(components[1])
                    .font(.title)
            }
        }
        .font(.largeTitle)
        .multilineTextAlignment(.center)
        .padding(.top)
    }
}

将字体替换为您的自定义字体


在您的环境中您可以使用它

struct BalanceDetailsView: View {
    //MARK: - PROPERTIES
    var balance: Float
    
    //MARK: - BODY
    var body: some View {
        VStack{
           BalanceView(balance: balance)
        }//:VSTACK
    }
}

这是一个在 SwiftUI 3(iOS 15、macOS 12 等)中使用新 AttributedString 的示例

var balanceString: AttributedString {
    var attributedString = AttributedString(balance.formattedWithSeparator)
    guard let separator = Formatter.withSeparator.decimalSeparator else { return attributedString }

    if let range = attributedString.range(of: separator) {
        attributedString[attributedString.startIndex...attributedString.index(beforeCharacter: range.lowerBound)]
            .font = Font.largeTitle
        attributedString[attributedString.index(afterCharacter: range.lowerBound)..<attributedString.endIndex]
            .font = Font.caption
    }

    return attributedString
}

我在这里使用了一些内置字体样式,但应该很容易替换。另请注意,由于我们在此处设置了 .font 属性,因此应将其从 Text

中删除