1

I have a bunch of UILabels inside a vertical UIStackView. The stack is making all labels with the same width and height.

Each label has a float in it, like this:

enter image description here

But this is ugly aesthetically. I want to align the numbers by the point. Like this:

enter image description here

One of my problem is that these floats are in different labels.

These numbers use this to format:

[NSString stringWithFormat:@"%.2f", value];

I don't have a clue if even it is possible. So, I have no code to show. Is it possible to do that? How?

EDIT: The floats are left aligned on the labels. Ok, I can reduce the labels width and align them to the right, but I am wondering if there is another solution in code because reducing the labels's width will cause other problems on the interface, crapping the whole thing.

Duck
  • 34,902
  • 47
  • 248
  • 470

3 Answers3

5

If, as your edit says, you don't want to set your labels' textAlignment to right (which is certainly the easiest solution), here's another solution. You need to do two things:

  1. You need to use a font with monospaced digits. In iOS 9 and later, the system font does not use monospaced digits by default, but there are programmatic ways to get a variant of the system font that does use monospaced digits. You can use +[UIFont monospacedDigitSystemFontOfSize:weight:], or if you already have a UIFont object, you can get a monospaced-digits variant (if there is one) by adding an attribute to its font descriptor. See this answer for code to do this (in Swift). Unfortunately there is no way to do this in a storyboard or xib without code.

  2. You need to add enough U+2007 FIGURE SPACEs to the beginning of each label's text to make them all the same length. For example, if they should all be five characters long:

    NSString *text = [NSString stringWithFormat:"%.2f", value];
    while (text.length < 5) {
        text = [@"\u2007" stringByAppendingString:text];
    }
    label.text = text;
    
Community
  • 1
  • 1
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
1

You can try to set the UILabel to right align, e.g. Something like:

label.textAlignment = NSTextAlignmentRight;

Or for the single digit before the point case you could prepend the Unicode FIGURE SPACE, U+2007, this is a space with the same width as a digit in fonts with equal width digits and so all numbers will be the same width.

CRD
  • 52,522
  • 5
  • 70
  • 86
1

If you really need to do that from code without reducing UILabel's width, you can subclass UILabel and override this method:

- (void)drawTextInRect:(CGRect)rect {
    UIEdgeInsets insets = {0, 0, 0, rightOffset};
    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}

Of course you should use right alignment as well.

alexburtnik
  • 7,661
  • 4
  • 32
  • 70