Search code examples
iosswiftiphoneswiftuiwatchos

change the fontsize of the decimal number in Swift/ SwiftUI


So i need to make the decimal places smaller than the actual number i will show you what i mean below.

this is the code i have:

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
This is the result I get This is the result I need

Solution

  • When you know exact format of your string, like in this case minimum string length will be 4("0.00") , you can safely use dropLast and dropFirst.

    I suggest moving 2 to priceFractionDigits constant to reduce constants usage in your code.

    Then you can use string concatenation, it'll align Text by baseline.

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

    Usage

    BalanceText(balance: balance)
    

    enter image description here