17

I have a UILabel which shows the output of a timer in the format MM:ss:SS (minutes, seconds, centiseconds), however it "shakes" from left to right as the width of the centiseconds changes - "11" is narrower than "33" for example.

Is there any way I can mitigate this? I've tried centring it, giving it a fixed width but they haven't seemed to help.

Chris Byatt
  • 3,689
  • 3
  • 34
  • 61
  • give a fixed width constraint to a label with highest wide possibility . For ex 33:33:33 should completely be contained in it. Give label some background color. It will solve your problem to some extent – Rajan Maheshwari Nov 19 '15 at 09:58
  • 1
    Using textkit you can specify that all numbers should be equal width. – milo526 Nov 19 '15 at 09:59

3 Answers3

28

Since iOS 9.0, the system font uses proportional digits. If you want monospaced digits, there's a variant font which you can obtain using +[UIFont monospacedDigitSystemFontOfSize:weight:]. This only works for the system font.

If you want to work with another font, you try to ask for a monospaced variant, but there may not be one. Given a UIFont, you can request its fontDescriptor, then ask that for a similar font descriptor that's monospaced (not just for digits) using -[UIFontDescriptor fontDescriptorWithSymbolicTraits:] and UIFontDescriptorTraitMonoSpace. You can then create a new font by passing the new font descriptor to +[UIFont fontWithDescriptor:size:].

However, I doubt there's a monospace variant of Impact. It's not suitable for your purpose.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
12

I had the same problem. @KenThomases answer works. Here's the Swift version:

// replace whatever font your using with this font instead to stop the shaking
UIFont.monospacedDigitSystemFont(ofSize: 19, weight: UIFont.Weight.regular)

ie:

yourLabel.font = UIFont.monospacedDigitSystemFont(ofSize: 19, weight: UIFont.Weight.regular)

FYI there are other UIFont.Weight weights:

.black, .bold, .heavy, .light, .medium, .regular, .semibold, .thin, .ultraLight

According to this other answer the fonts below are system generated fonts that are also monospaced so they won't shake either:

Courier

Courier-Bold

Courier-BoldOblique

Courier-Oblique

CourierNewPS-BoldItalicMT

CourierNewPS-BoldMT

CourierNewPS-ItalicMT

CourierNewPSMT

Menlo-Bold

Menlo-BoldItalic

Menlo-Italic

Menlo-Regular

ie:

// no shaking
yourLabel.font = UIFont(name: "Menlo-Regular", size: 19)

If your using just numeric digits then HelveticaNeue is also monospaced and it doesn't shake but it's questionable. Read the comments below this answer before using this font.

ie:

// no shaking but apparently you can only use numbers not letters
yourLabel.font = UIFont(name: "HelveticaNeue", size: 19)
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
4

Use A monospaced font, also called a fixed-pitch, fixed-width, or non-proportional font, is a font whose letters and characters each occupy the same amount of horizontal space. Examples of monospaced fonts include Courier, Courier New, Lucida Console, Monaco, and Consolas

Varun Naharia
  • 5,318
  • 10
  • 50
  • 84
  • only Courier, Courier New are included in Xcode project. But yeah those fonts have equal width per any character. nice. – coolcool1994 Jan 27 '18 at 23:24