How to make a UILabel truncate at character boundaries? - ios

I have some UILabels next to each other horizontally which will contain names.
I can't find any way of getting the text to be truncated at a character boundary - I've tried a line break mode with NSLineBreakByCharWrapping but the characters get chopped off in the middle
I've tried the other line break modes but can't get rid of the partial character (x in this particular example), I don't want part of a character displayed obviously as it looks no good.
Its not feasible to limit the output to a hard coded number of characters because iiiiiiii is a totally different width to wwwwwwww for example.
Also I don't want … appearing within the text because as its narrow then there would be too few characters left if part of the available space is consumed with ...
contactItem.name.frame = nameFrame;
contactItem.name.font = [UIFont systemFontOfSize:12];
contactItem.name.textColor = [UIColor whiteColor];
contactItem.name.textAlignment = NSTextAlignmentCenter;
contactItem.name.lineBreakMode = NSLineBreakByCharWrapping;
[self.scrollView addSubview: contactItem.name];
contactItem.name is the UILabel(s). nameFrame is getting horizontally incremented for each contactItem.

Maybe calculate text size yourself and react when it's too long?
Calculating UILabel Text Size
I don't know if this the simplest solution for this problem - but for sure it's the working solution.

Related

Aligning floats with two decimals by the point [duplicate]

This question already has an answer here:
Decimal point alignment in iOS UILabel during countdown?
(1 answer)
Closed 5 years ago.
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:
But this is ugly aesthetically. I want to align the numbers by the point. Like this:
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.
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:
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.
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;
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.
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.

How to dynamically calculate the number of characters a UILabel holds before it gets truncated?

I have a UILabel that is configured with dynamic parameters:
textLabel.font = UIFont.systemFontOfSize(some_dynamic_size, weight: some_dynamic_font_weight)
textLabel.numberofLines = some_dynamic_number_lines
textLabel.frame = CGRectMake(0, 0, dynamic_width, dynamic_height)
How to calculate the number of characters this UILabel can hold before it gets truncated?
Calculate how tall the label would want to be given its font, text, and width. If that is taller than you want to make it, the text won't all fit.
The issue is that your label will be able to fit more or less text given on the font that you use and the size that it is set too. If you set that to a standard size say for instance San Francisco at 12pt then you will still have a varying amount of letters that can fit because not all letters are the same width for instance 'WWW' is allot bigger than ' lll ' but you could determine a "best estimate" by taking the average letter width. Then dividing the size of the label by that then you would have a general idea of how many letters could fit but you also need to account for the '...' that is inserted.
But I would suggest not concatenating at all and just make the text a variable size so it can shrink and show the whole word. I suggest looking into 'dynamic text' but I don't know what your application is so that may not be the best suggestion. Hope that helps 😜

How to remove the extra padding below an one line UILabel

I wanna to use a UILabel to show some words which is sent from Server,these words which i set them as NSMutableAttributeString sometimes only occupy one line (only in this case, the problem comes).
I intend to get the exact space which the label would take up,but when the label only takes up one line,and very important — i set the NSMutableAttributeString with lineSpacing (10px,NSMutableParagraphStyle),but this,unexpectedly,
would also works when even there is only one line here — the problem shows up as some extra padding below the word (i test with some chinese word,but attention: if the words takes up more than one line, there is no problem). and the weird
story is — if the word is purely english or Arabic numerals,the extra padding won't exist)
the following pics may shows the problem a little clearly:
1.English words -- oneline (no extra padding)[test words:today 0987776]
2.Chinese words -- oneline (some extra padding)[test words:今天天气好啊!]
Hope someone would help . Thx a lot.
use sizeToFit on a label to the size required by the text
[yourlabelName sizeToFit];
any other padding would be from the font, the label itself doesn't apply any other padding
// baselineOffset, It was totally hit and miss Hope to help you
[attributedString addAttribute:NSBaselineOffsetAttributeName value:#(baselineOffset) range:range];

Auto size UILabel text

I have a UILabel with multi lines. I'm trying to get the text to auto size, and fit on the line it's in. So instead of:
longe
st
The text size should become smaller so that it can fit on the same line:
longest
Note: I only need it for the first line.
I tried the following:
label.adjustsFontSizeToFitWidth = YES;
label.minimumScaleFactor=3.0;
That didn't work, so I tried label.minimumScaleFactor=3.0 / 9; (9 is the font size.) That also didn't work.
I have a UILabel with multi lines
Well, that's the problem. The automatic size adjustment feature of UILabel works only for 1-line UILabels (i.e. numberOfLines must be 1).
You might be happier with two labels, one being a single-line UILabel for the first line which can shrink its size, the other for the remaining lines.

Calculate characters that fit a fixed rect TextView

I have seen here people needing to calculate the size of the NSString given a size but I need to do the opposite.
Given a specified rect (or fixed UITextView, or multiline UILabel, no scrolling) I need to know:
if it managed to show all the chars of my NSString
if not, what is the last char shown
So that I can display the remaining text in another UITextView (of course if I could use a single UITextView I would not have this problem).
At first it seems a simple thing to do, but actually I am not finding a way, intuitively I think I could use either UITextView's:
textView.contentSize.height;
or NSString's:
sizeWithFont:constrainedToSize:lineBreakMode:
or a combination of the two, but I need to be precise and those methods do not help me in telling what is the last character that managed to fit the visible area of the UITextView.
Not sure if this is actually possible, but is a requirement of my client who thinks programming iOS is like printing a newspaper and expects to be able to format text around an image....
You could maybe get the maximum height of one line of text from a one character long string.
If you use that with sizeWithFont:constrainedToSize:lineBreakMode: then you should be able to know if your text runs onto more than one line (if the cgsize height is greater than the height of one line of text).
In order to find out the last character (or word) you would have to loop around the length of the string adding characters (or words) as you go and checking for when the cgsize height increases to add a new line, this will give you the character point when to split into multiple strings ( for multiple fields/labels/textviews ) or when to insert line breaks into the text ( if using a single multi-line textview or label ).
I hope you find an easier way...

Resources