Truncate part of text in UILabel - ios

My requirement is that I need to display text in label in such a way that if the length of text is too big to accommodate in one line, i need to truncate it at the end in such a way that only the last few characters(usually a number b/w 1-1000 so text length may vary.) are visible and the text before it is truncated with "...".
So the text will look something like "abcdefgijk...10"
Is there any way I can achieve this?

UILabel *contentLabel = [[UILabel alloc]initWithFrame:CGRectMake(50,100, 150, 30)];
contentLabel.text = #"abcdefghijklmnopqrstuvwxyz10";
contentLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
Add this label to your display. You should get a output something like this
abcdefghijklmnopq...10

Swift 4:
Incase someone runs into this issue like i did,
you need to set your label.numberOfLines = 1
if you have it set to 0 it will truncate at a space.
so your code should look like
label.numberOfLines = 1
label.lineBreakMode = .byTruncatingTail
label.adjustsFontSizeToFitWidth = false

For everyone looking for more recent solution, swift 3 :
yourLabel.lineBreakMode = .byTruncatingMiddle;

Try this:
label.lineBreakMode = NSLineBreakByTruncatingMiddle;
UILineBreakModeMiddleTruncation is deprecated from iOS 6.0.

In Storyboard
Select the Label which you want to truncate the characters.
Choose Attributes Inspector.
Under Label attributes. You can find Line Break
Done.

there are many methods in NSString class use -length and then use any of these
– substringFromIndex:
– substringWithRange:
– substringToIndex:
create a temporary string using NSString stringwithFormat, put your desired charecters you get from substringTo index and "....." then your numbers from string by substringFromIndex.
hope this helps

You can start with finding the length of characters that can be placed in a line, say 'n' characters. You can take help of this link to determine 'n' How to know if NSString fits in UILabel or not and index of the last string which fits?. Next, find the length of the string. If it exceeds n, then extract the last two characters. Ex
NSString * fooString = #"a very long string";
NSString * s2 = [fooString substringWithRange:NSMakeRange([fooString length]-3, 2)];
NSString * s1 = [fooString substringWithRange:NSMakeRange(0 , n-5)];
NSString * newString = [NSString stringWithFormat:#"%#...%#",s1,s2];

We have different Line Break modes for UILabel like
Truncate Head,
Truncate Middle,
Truncate Tail
In Xib you can set the Line Break mode what ever you want

If you using XIB file..
select --> UILable and
select --> Attribute inspector tag and change into Line Breaks-->Truncate tail
simply way to truncate characters...

Here is how to use it, NSLineBreakByTruncatingMiddle
UILabel *temp = [[UILabel alloc]initWithFrame:CGRectMake(5,75, 100, 50)];
[temp setBackgroundColor:[UIColor lightGrayColor]];
temp.lineBreakMode = NSLineBreakByTruncatingMiddle;
temp.text = #"HelloBoss997";
Output :
Hello...s997

Related

Xcode UILabel bug? Line spacing cropping text with a UILabel

I have some designs I'm following for an iOS project. The font used is Avenir with relatively tight line spacing.
Some of these labels will have dynamic text, so I can't just make the label's size larger since the size should be determined by the content.
By default line spacing for a UILabel ends up pretty large.
If I adjust the Line Height Multiple or the Max Height, the text along the top ends up cropped.
It should behave like this (Affinity Designer)...
Is there a way to handle this?
Thanks for your help!
This works for me. By adding
minimumLineHeight
let string = NSMutableAttributedString(string: venue.name)
let style = NSMutableParagraphStyle()
style.lineHeightMultiple = 0.68
style.minimumLineHeight = nameLabel.font.lineHeight
string.addAttribute(NSAttributedString.Key.paragraphStyle,
value: style,
range: NSMakeRange(0, venue.name.count))
nameLabel.attributedText = string
Unfortunately the UILabel has several quirks when it comes to vertical adjustments. A somewhat hacky solution is to move the baseline of the first line down as needed. Depending on if your string ends with a newline, and the amount of tightening you do, you might need to add one or two extra newlines also, otherwise the rendering engine will clip the last line.
The code snippet assumes that self.label already has an attributed string assigned to it, and that it has line separator character 0x2028 between the lines. This is usually true when entering multi-line text in IB.
// 0x2028 is the unicode line separator character
// Use \n instead if it is what you have
// or calculate the length of the first line in some other way
NSInteger lengthOfFirstLine = [self.label.text componentsSeparatedByString:#"\u2028"][0].length;
NSMutableAttributedString *s = [[NSMutableAttributedString alloc] initWithAttributedString:self.label.attributedText];
// Add two more blank lines so that the rendering engine doesn't clip the last line
[s appendAttributedString:[[NSAttributedString alloc] initWithString:#"\n\n"]];
// Move the baseline offset for the first line down
// the other lines will adjust to this
// 50 is a value you will have to find what looks best for you
[s addAttribute:NSBaselineOffsetAttributeName value:#(-50) range:NSMakeRange(0, lengthOfFirstLine)];
self.label.attributedText = s;

How to keep a space at the end of the string in ios, objective C without changing its UI(position)

I have created a label programmatically.it's with is equal to the device width and I have aligned it to right.so it shows the text from right.
like this
titleLabel.textAlignment = NSTextAlignmentRight;
then I gave a text to the label.
titleLabel.text = #"Flight Summary";
but I want to keep a space after y letter in summary, without decreasing the width of the label.I tried with using string format like this.
titleLabel.text =[NSString stringWithFormat:#"%# ", #"Flight Summary "];
but nothing happned.how can I do that.hope your help for this.thanx.
To reduce the complexity of subclassing, you can take UIView and UIlabel, set frame of UIView to screen width and take UILabel frame as screenwidth - 8 (or whatever pixels is appropriate for you). Manage the frames and add both to mainview, this way you will be able to achieve the look.
Try this
titleLabel.text = #"abcd exadgdf \u{200c}""
You can also do one more thing. You can use attributed string and set attributed text to titlelabel without formatting string like this
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:#"ABCD "];
titleLabel.attributedText = attrString;

Adding multiple lines to a UILabel that is updated by a UITextField

So i'm making an application where the user converts the data from a UITextField into a UILabel. However, when updating a large amount of text instead of overflowing into another line, it simply displays '...' when there are too many words. I've tried changing the number of lines in the UILabel, even changing it to '0' which should mean the text displayed should fit the words in the UITextField, but this isn't the case. The following code I have for the UITextField to the UILabel is:
- (IBAction)add:(id)sender {
NSString *input = text1.text;
label1.text = input;
NSString *Input = text2.text;
label2.text = Input;
I'm new to developing and I've checked documentation and have found nothing. I did notice someone saying I should use a UITextField, however this doesn't suit my needs as to what i require the UILabel to display.
Maybe try setting the lineBreakMode property of the UILabel to NSLineBreakByWordWrapping, as the default value for this property is actually NSLineBreakByTruncatingTail which could explain the '...' that you're experiencing when the label has too much text. Also make sure the adjustsFontSizeToFitWidth property is set to NO.
textLabel.adjustsFontSizeToFitWidth = NO; // this is default value
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.numberOfLines = 0;
Options for UITextView that you may have not seen
UITextView * _descriptionText = [UITextView new];
[_descriptionText setTextAlignment:NSTextAlignmentLeft];
[[_descriptionText textContainer] setMaximumNumberOfLines:11];
[[_descriptionText textContainer] setLineBreakMode:NSLineBreakByTruncatingTail];
Not sure if this helps, but combining this with Bamsworlds answer should do it

Calculate part of the text truncating the UILabel

I have a UILabel that contains some text that is more than the size of UILabel. I don't want to change UILabel size i only want one line in it. So my question is how can i skip(remove) the text from end that is causing the UILabel to truncate tail?
I'm afraid there is no a direct method to calculate. But as you can get the size or bounds of a text using boundingRectWithSize:options:attributes: you can iterate using a dichotomic search algorithm and find the string position to cut from.
Use this line to set up the line break mode of your UILabel:
self.lineBreakMode = UILineBreakModeWordWrap
Try this,
I think you are asking for character wrapping trick.
First try in XIB
yourLabel.numberOfLines = 1;
yourLabel.lineBreakMode = NSLineBreakByCharWrapping;
//or
yourLabel.lineBreakMode = NSLineBreakByClipping;
I was doing a similar thing on UITableView Cell recently. This approach is flexible, as you can set any number of lines depending on height you have available. Everything else will be truncated. Check it out:
CGSize maxNameLabelSize = CGSizeMake(350,60); //setting height, you can limit it to one line depending on the font
UILabel *eventName = (UILabel*) ([activityCell.contentView viewWithTag:EVENT_TITLE]);
//Set value here
eventName.text = event.name;
CGSize expectedNameLabelSize = [eventName.text sizeWithFont:eventName.font constrainedToSize:maxNameLabelSize lineBreakMode:eventName.lineBreakMode];
CGRect newNameFrame = eventName.frame;
newNameFrame.size.height = expectedNameLabelSize.height;
eventName.frame = newNameFrame;
Does it makes sense?

How to add line break for UILabel?

Let see that I have a string look like this:
NSString *longStr = #"AAAAA\nBBBBB\nCCCCC";
How do I make it so that the UILabel display the message like this
AAAAA
BBBBB
CCCCC
I don't think \n is recognized by UILabel, so is there anything that I can put inside NSString so that UILabel knows that it has to create a line break there?
Use \n as you are using in your string.
Set numberOfLines to 0 to allow for any number of lines.
label.numberOfLines = 0;
Update the label frame to match the size of the text using sizeWithFont:. If you don't do this your text will be vertically centered or cut off.
UILabel *label; // set frame to largest size you want
...
CGSize labelSize = [label.text sizeWithFont:label.font
constrainedToSize:label.frame.size
lineBreakMode:label.lineBreakMode];
label.frame = CGRectMake(
label.frame.origin.x, label.frame.origin.y,
label.frame.size.width, labelSize.height);
Update : Replacement for deprecatedsizeWithFont:constrainedToSize:lineBreakMode:
Reference, Replacement for deprecated sizeWithFont: in iOS 7?
CGSize labelSize = [label.text sizeWithAttributes:#{NSFontAttributeName:label.font}];
label.frame = CGRectMake(
label.frame.origin.x, label.frame.origin.y,
label.frame.size.width, labelSize.height);
Use option-return when typing in the little box in Interface Builder to insert a line feed (\n). In Interface Builder's Label attributes, set # Lines = 0.
Select the label and then change Lines property to 0 like in the above image, and then use \n in your string for line break.
In the interface builder, you can use Ctrl + Enter to insert /n to the position you want.
This way could implement the following situation
aaaaaaaaaa
If you read a string from an XML file, the line break \n in this string will not work in UILabel text. The \n is not parsed to a line break.
Here is a little trick to solve this issue:
// correct next line \n in string from XML file
NSString *myNewLineStr = #"\n";
myLabelText = [myLabelText stringByReplacingOccurrencesOfString:#"\\n" withString:myNewLineStr];
myLabel.text = myLabelText;
So you have to replace the unparsed \n part in your string by a parsed \n in a hardcoded NSString.
Here are my other label settings:
myLabel.numberOfLines = 0;
myLabel.backgroundColor = [UIColor lightGrayColor];
myLabel.textColor = [UIColor redColor];
myLabel.font = [UIFont fontWithName:#"Helvetica Neue" size:14.0];
myLabel.textAlignment = UITextAlignmentCenter;
Most important is to set numberOfLines to 0 (= unlimited number of lines in label).
No idea why Apple has chosen to not parse \n in strings read from XML?
You have to set the numberOfLines property on the UILabel. The default is 1, if you set it to 0 it will remove all limits.
Important to note it's \n (backslash) rather than /n.
For those of you who want an easy solution, do the following in the text Label input box in Interface Builder:
Make sure your number of lines is set to 0.
Alt + Enter
(Alt is your option key)
Cheers!
In Swift 2.2, > iOS 8
I've set Lines = 0 on Storyboard, under Attribute Inspector and linked a referencing outlet to the label. Then use in controller like this:
#IBOutlet weak var listLabel: UILabel!
override func viewDidLoad() {
...
listLabel.text = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8"
}
In xCode 11, Swift 5 the \n works fine, try the below code:
textlabel.numberOfLines = 0
textlabel.text = "This is line one \n This is line two \n This is line three"
Just do it like this
NSString * strCheck = #"A\nB";
strCheck = [strCheck stringByReplacingOccurrencesOfString:#"\\n" withString:#"\n"]; //This is to prevent for fetching string from plist or data structure
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text = strCheck;
// DO not forget to set numberOfLines to zero
UILabel* locationTitle = [[UILabel alloc] initWithFrame:CGRectMake(5, 30, 230, 40)];
locationTitle.font = [UIFont systemFontOfSize:13.0];
locationTitle.numberOfLines = 0;
locationTitle.text = [NSString stringWithFormat:#"Eaton industries pvt. Ltd \nUK Apr 12"];
[cell addSubview:locationTitle];
If your using a UILabel you have to remember that the default setting is 1 line, so it does not matter how many breaks you add (\n or \r), you need to make sure it is set to more than one line so it could be allowed to append more lines.
One alternative is to use UITextView which is really meant for multilines.
You can easily achieve this in XCode attribute section of the UILabel, see screenshot:
On Xcode 6, you can just use \n even inside a string when using word wrap. It will work. So for example:
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 100, screenRect.size.width, 50)];
label.textAlignment = NSTextAlignmentCenter;
label.text = #"This will be on the first line\nfollowed by a line under it.";
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;
In my case also \n was not working, I fixed issue by keeping number of lines to 0 and copied and pasted the text with new line itself for example instead of Hello \n World i pasted
Hello
World
in the interface builder.
Just using label.numberOfLines = 0;
textLabel.text = #"\nAAAAA\nBBBBB\nCCCCC";
textLabel.numberOfLines = 3; \\As you want - AAAAA\nBBBBB\nCCCCC
textLabel.lineBreakMode = UILineBreakModeWordWrap;
NSLog(#"The textLabel text is - %#",textLabel.text);
For anyone else that might have trouble with sizeWithFont:constrainedToSize:lineBreakMode: or anyone switching to ios8 (the method is deprecated as of ios7), I adjusted my height by using sizeToFit instead.
UILabel *label;
label.numberOfLines = 0;
// Setup label with desired settings
...
[label sizeToFit];
label.frame = CGRectMake(label.frame.origin.x, // Or use any desired origin
label.frame.origin.y,
label.frame.size.width, // Or use any desired width
label.frame.size.height);
NSCharacterSet *charSet = NSCharacterSet.newlineCharacterSet;
NSString *formatted = [[unformatted componentsSeparatedByCharactersInSet:charSet] componentsJoinedByString:#"\n"];
It seems wrong to me to change the label frame sizes especially when using autolayout. Using the appendFormat method seems more appropriate. Here is my example:
NSMutableString *list = [[NSMutableString alloc] init];
NSArray *textArray = #[#"AAAA", #"BBBB"];
for (NSString *string in textArray) {
[list appendFormat:#"%#\n", string.mutableCopy];
}
self.label.text = list;
self.label.numberOfLines = 0;
If you set your UILable properties from Plain to Attributed...the UILabel will hold multiline text no matter how many paragraphs for along as your UILabel height and width are set to fit the screen area you want to display the text in.
I have faced same problem, and here is, how i solved the problem. Hope this will be helpful for someone.
// Swift 2
lblMultiline.lineBreakMode = .ByWordWrapping // or use NSLineBreakMode.ByWordWrapping
lblMultiline.numberOfLines = 0
// Objective-C
lblMultiline.lineBreakMode = NSLineBreakByWordWrapping;
lblMultiline.numberOfLines = 0;
// C# (Xamarin.iOS)
lblMultiline.LineBreakMode = UILineBreakMode.WordWrap;
lblMultiline.Lines = 0;
on Xcode 6, I can use \n without problem on swift programmatically

Resources