how to make characters equal width in UILabel
Asked Answered
H

4

6

I have a problem when using UILabel.

enter image description here

I have two labels here(above images), they have equal font and equal width, textAlignment are both left, they both have 10 characters, but each character have different width so it can't be aligned one by one, I‘m trying to add spacing dynamically but I failed to do that, so how can I fix it? thanks a lot~

Hardiness answered 25/7, 2016 at 5:40 Comment(0)
S
4

The reason it fails is you are using a proportional font, meaning: characters will take up an individual width. An i will just take a fraction of a m.

Use a monospaced font, than all characters will have the same width.

label.font = UIFont(name:"Courier", size: 17)

for the same reason Courier and other monospaced fonts are used in code editors.

Sutter answered 25/7, 2016 at 6:21 Comment(1)
Helvetica Neue has mono spaced digits so in this case a good option too.Palmirapalmistry
M
12

No need to use a monospace font if you're targetting iOS 7+!

From the UseYourLoaf blog:

let bodyFontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: UIFontTextStyle.body)
let bodyMonospacedNumbersFontDescriptor = bodyFontDescriptor.addingAttributes(
    [
        UIFontDescriptorFeatureSettingsAttribute: [
            [
                UIFontFeatureTypeIdentifierKey: kNumberSpacingType,
                UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector
            ]
        ]
    ])

let bodyMonospacedNumbersFont = UIFont(descriptor: bodyMonospacedNumbersFontDescriptor, size: 16.0)

myLabel.font = bodyMonospacedNumbersFont
Mallina answered 18/4, 2017 at 18:12 Comment(1)
Working perfectly on iOS 15, and I found some additional info about this: Font Feature Registry - AppleSeabrooke
S
4

The reason it fails is you are using a proportional font, meaning: characters will take up an individual width. An i will just take a fraction of a m.

Use a monospaced font, than all characters will have the same width.

label.font = UIFont(name:"Courier", size: 17)

for the same reason Courier and other monospaced fonts are used in code editors.

Sutter answered 25/7, 2016 at 6:21 Comment(1)
Helvetica Neue has mono spaced digits so in this case a good option too.Palmirapalmistry
M
0

You can adjust letter spacing like this, using NSAttributedString.

In Objective-C:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"111111111"];
[attributedString addAttribute:NSKernAttributeName
                         value:@(4)
                         range:NSMakeRange(0, 9)];

self.label.attributedText = attributedString;

In Swift:

let attributedString = NSMutableAttributedString(string: "000000000")
attributedString.addAttribute(NSKernAttributeName, value: CGFloat(1.5), range: NSRange(location: 0, length: 9))

label.attributedText = attributedString

For Specific you can change value of NSKernAttributeName for 1 set 4 and for other 1.5.

OutPut will be Like :

enter image description here

Mallee answered 25/7, 2016 at 5:49 Comment(1)
sorry, i didn't realize i add a comment because of the bad network. i have a new question, if i change the text "1111111111" to "0123456789", i can't add the space correctly, can you help me ,thanks a lot ! ps: text is return by servers, isn't static at all.Hardiness
I
0

This is caused by the SF font. If you prefer using system font, we can use monospacedSystemFont / monospacedDigitSystemFont:

// Number & Alphabet
UIFont.monospacedSystemFont(ofSize: 24, weight: .medium)

// Number only
UIFont.monospacedDigitSystemFont(ofSize: 24, weight: .medium)
It answered 15/5, 2022 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.