UILabel truncate text not working - objective-c

I set the numberOfLines to 1 in the IB, but when I set the text to a long string, it doesn't truncate. If I set the numberOfLines to 2, the truncate works fine.What should I do to truncate a long string into a single line?

simple, set the following properties:
label.adjustsFontSizeToFitWidth = NO;
label.lineBreakMode = NSLineBreakByTruncatingTail;

If you're using attributed string and having set paragraph style to the attributed string: make sure you're passing paragraphStyle.lineBreakMode = .byTruncatingTail.

If using auto layout, in my case, there was a constraint missing. The UILabel grows its width if no constraint is set on its width/trailing. Once its width is limited, for instance to its superview, the truncation occurs.

You probably have a constraint on a label in that section that is making things go haywire.
Double check your constraints or remove them for that label or other controls in that section.
The storyboard option for a label: "Line Breaks:Truncate Tail" will to the work you are looking for.

If you set the label's autoshrink to "Fixed Font Size" in IB, you will always get a truncatation when the string width beyond the label width. I guess you happened to set that to "Minimum Font Scale" or "Minimum Font Font", which will lead a resizing when the string is too long.
(Xcode 4.5, other version of Xcode and IB may be different property name)

I make two functions, that will help you to do your work.
Basic:
This solution I made for task:
"minimize font to my min size of font and then put as much info, as possible, but not bigger then maximum width"
takeFineFont... function parameters:
(UIFont*)font - font of the your label (titleLabel.font)
(NSString*)string - text in your label (titleLabel.text)
(CGSize)limitStringSize - limit size.
limitStringSize.width - width limit of your label (Upper limit)
limitStringSize.height - height limit of your label (Lower limit)(actually, size of font)
-(UIFont*)takeFineFontSize:(UIFont*)font
forText:(NSString*)string
andLimit:(CGSize)limitStringSize{
UIFont* resultFont = [UIFont fontWithName:[font fontName] size:[font pointSize]];
if(limitStringSize.width != 0 && limitStringSize.height != 0){
CGSize currentSize = [string sizeWithFont:resultFont];
while(/* change font width with upper bound */
currentSize.width > limitStringSize.width
&&
/* change font height with lower bound */
currentSize.height > limitStringSize.height){
/*change height and take new width*/
currentSize.height -= 1;
currentSize.width = [string sizeWithFont:[resultFont fontWithSize:currentSize.height]].width;
}
resultFont = [resultFont fontWithSize:currentSize.height];
}
return resultFont;
}
-(double)takeFineWidthForFont:(UIFont*)font
forString:(NSString*)string
andLimit:(double)widthLimit{
return MIN([string sizeWithFont:font].width, widthLimit);
}
Suppose, that you have big string in UILabel* titleLabel
And you define somewhere:
#define maximumLengthOfYourLabel 300
#define minimumSizeOfFont 14
what you will do now? just do this peace of code:
-(void)updateTitleLabelWithBigText:(NSString*)string{
/*change text*/
self.titleLabel.text = string;
/*take pretty small font*/
self.titleLabel.font = [self takeFineFontSize:self.titleLabel.font
forText:self.titleLabel.text
andLimit:CGSizeMake(maximumLengthOfYourLabel,minimumSizeOfFont)
];
/*if your text still big, take minimal width and trunctate it*/
self.titleLabel.width = [self takeFineWidthForFont:self.titleLabel.font
forString:self.titleLabel.text
andLimit:maximumLengthOfYourLabel];
self.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
}

Ensure you are not calling sizeToFit() on your label. It will override the label and constraint settings.

set numberOfLines to 0, this will let you expand uilabel content vertially without truncating its width.

Perhaps this method can help you:
[myLabel sizeToFit];
The label won't be truncated but it will adjust the label size to fit in one line.

Related

Equal sized cells in NSSegmentedControl

For my NSSegmentedControl, I use it do display a bar to control a NSTableView. I have code set up to control the size programmatically:
for (NSInteger i = 1; i <= numberOfSegments; i++) {
CGSize textSize = [[NSString stringWithFormat:#"Workspace %ld", (long)i] sizeWithAttributes:#{NSFontAttributeName: [NSFont systemFontOfSize:13.0f]}];
NSInteger segmentWidth = self.workspaceControl.frame.size.width / numberOfSegments;
if (textSize.width > segmentWidth) {
[self.workspaceControl setLabel:[NSString stringWithFormat:#"%ld", (long)i] forSegment:i - 1];
} else {
[self.workspaceControl setLabel:[NSString stringWithFormat:#"Workspace %ld", (long)i] forSegment:i - 1];
}
[self.workspaceControl setWidth:segmentWidth forSegment:i - 1];
}
This works, by a small problem occurs.
At the beginning (with one segment) it looks like this:
As I change the value, the right side gets clipped slightly.
And then back to one segment:
The constraints are as follows:
Im very puzzled by the clipping (probably because a couple pixels t0o large), but I have no idea how to fix it, or is there a better way to get evenly spaced cells?
In my testing the generated width constraints of the NSSegmentedControl segments appear to round to whole numbers despite setWidth(_ width: CGFloat, forSegment segment: Int) taking a CGFloat. Thus the total width of the segments can add up to more than the width of the control itself.
To get even segments pass segmentWidth through the floor. Also, set a manual width for the control and constrain it horizontally by the centerXAnchor instead of by the leading and trailing anchors to preserve its center-alignment.
Drawbacks: the width must be hard-coded and the left and right margins may not match your other views exactly.

Is there a way to limit the width of text in UITextView

I have UITextView where I need to control where text start and end.
This because I use bubble as background image for UITextView and I need to display the text inside the bubble image.
So far,I have been able to control where text start using:
self.contentOffset = (CGPoint){.x = -10, .y = -10};
but I have no clue how to control where text end. Currently, by default it uses all UITextView width.
Will the bubble grow in height as the text stretches? Or will the bubble be limited to 1 line? Either way, I think you should use a different approach to deal with this problem.
Use -sizeWithFont:constainedToSize:lineBreakMode: on an NSString instance to figure out what the size is of the text. If the size is greater then the value allowed by you, stop allowing input (if that's your goal) or increase hight of the bubble and allow text to continue on next line.
You would typically perform these recalculations upon text input, which means you'd implement the UITextViewDelegate method -textView:shouldChangeTextInRange:replacementText: according to the above suggestions.
-- or --
Just limiting the size of the textView and setting the lineBreakMode & numberOfLines might also be sufficient for your purposes.
define #define TEXT_LENGTH 25 // Whatever your limit is
The UITextView calls this method whenever the user types a new character or deletes an existing character.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSUInteger newLength = (textView.text.length - range.length) + text.length;
if(newLength <= TEXT_LENGTH)
{
return YES;
} else {
NSUInteger mySpace = TEXT_LENGTH - (textView.text.length - range.length);
textView.text = [[[textView.text substringToIndex:range.location]
stringByAppendingString:[text substringToIndex: mySpace]]
stringByAppendingString:[textView.text substringFromIndex:(range.location + range.length)]];
return NO;
}
}
Use replacementText not replacementString in method, so careful with the different between replacementString and replacementText.

Render UILabel in multiple line in iOS5?

I'm trying to render my UILabel in multiple line.
i've tried:
CGRect rect2 = CGRectMake(100, 45, 150, 60);
FontLabel *addresLbl1 = [[FontLabel alloc] initWithFrame:rect2
fontName:#"arial" pointSize:12.0f];
//#006000
addresLbl1.textColor = [UIColor colorWithRed:84/255.0 green:84/255.0 blue:84/255.0 alpha:1.0];
addresLbl1.text = #"401 King St\\nToronto, Ontario, M5V1K1\\nCanada";
//[addresLbl1 setTextAlignment:UITextAlignmentCenter];
addresLbl1.backgroundColor = nil;
addresLbl1.opaque = NO;
[cell.contentView addSubview:addresLbl1];
[addresLbl1 release];
but it is rendered as 401 King St\nToronto, Ontario, M5V1K1\nCanada
Note that this label is added on cell of UITableView.
I need new line from the position of '\n' in string and this string will come from server, so position of '\n'may vary
You shouldn't use doubble backslashes.
\\ is the code used for \, so \\n will be parsed and printed as \n
So you're code should be like this:
addresLbl1.text = #"401 King St\nToronto, Ontario, M5V1K1\nCanada";
addresLbl1.numberOfLines = 0;
By default UILabel sets its property numberoflines to 1, which means your text will be rendered in one line. Try to set that property to 0, as indicated by the documentation
This property controls the maximum number of lines to use in order to
fit the label’s text into its bounding rectangle. The default value
for this property is 1. To remove any maximum limit, and use as many
lines as needed, set the value of this property to 0.
If you constrain your text using this property, any text that does not
fit within the maximum number of lines and inside the bounding
rectangle of the label is truncated using the appropriate line break
mode.
When the receiver is resized using the sizeToFit method, resizing
takes into account the value stored in this property. For example, if
this property is set to 3, the sizeToFit method resizes the receiver
so that it is big enough to display three lines of text.
you need to first set numberOfLines to 0, and then
unichar chr[1] = {'\n'};
NSString *singleCR = [NSString stringWithCharacters:(const unichar *)chr length:1];
[yourLabel setText:[NSString stringWithFormat:#"new%#line",singleCR]];
this will ensure what you wanted.
For multiple lines you can use UILabel property numberOfLines as
label.numberOfLines = 3;
In your case your text can fit only in one line so if you want it in multiple lines better you should define 3 different labels.

Is there a way to obtain the length of the cell's subtitle (detailedTextLabel)?

as mentioned in the question, I would like to obtain the length of the subtitle (topic.context) and use it to make certain decisions (see my code snippet below)
cell.detailTextLabel.text = topic.context;
NSString *fanLabelText = [NSString stringWithFormat:#"%i fans",topic.num_fans];
if (topic.context && ![topic.context isEqual:[NSNull null]] && topic.context.length > 46)
{
thisFanLabel.frame = CGRectMake(320 - 150, -10, 100, 44);
}
else
{
thisFanLabel.frame = CGRectMake(320 - 150, 0, 100, 44);
}
Basically, I want to know when the subtitle will reach a certain length so that I can adjust the fan label to be shifted upwards (as seen in the diagram below). Currently the fans label is being overlapped by the subtitle, I want to be able to shift the label upwards when this happens.
So what would be the best way to obtain the accurate length of the subtitle?
You can check the size of a string with a certain font by using the following lines:
CGSize maxSize = CGSizeMake(9999,9999);
UILabel *myLabel = cell.detailTextLabel;
CGSize sizeOfString = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:maxSize
lineBreakMode:myLabel.lineBreakMode];
In "sizeOfString" you should now have the size of your detailLabel.
See NSString's -sizeWithFont: and related methods.

Size of label changes after being set, depending on string

I am facing an issue in getting the correct frame for two different strings. I am running two strings through the below code:
UILabel *myLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
myLabel.lineBreakMode = UILineBreakModeWordWrap;
myLabel.numberOfLines = 2;
myLabel.textAlignment = UITextAlignmentCenter;
myLabel.font = [UIFont boldSystemFontOfSize:11];
myLabel.text = #"About Stores"
myLabel.text = #"About Rivers"
CGSize myLabelSize = CGSizeMake(70,28);
[myLabel sizeWithFont:myString.font // <-- One of two strings
constrainedToSize:aLabelSize
lineBreakMode:UILineBreakModeWordWrap];
Result for myString1 => Width: 70, Height: 28
Result for myString2 => Width: 70, Height: 14
Why there is a difference here?
Issues I see:
1
NSString has no font property. You might want to replace "myString.font" with UILabel.font where the UILabel is to be replaced by the instance of UILabel you plan to use to display the string.
2
sizeWithFont is supposed to return a CGSize that you store in an instance of CGSize.
Seems like you're not very clear on using this. I've posted an answer on how to correctly use sizeWithFont. You should check that out here : Place two UILabels side by side left and right without knowing string length of text in left label
By the way, that's why you see a difference in the heights... I think a garbage value is being passed in as the font size argument. If you hardcode the font size argument, you'll see consistent results.
just replace the code n give a try.....i don kno if it works jus check :)
[myLabel sizeWithFont:[UIFont fontWithName:#"Helvetica-Bold" size:11]
constrainedToSize:myLabelSize lineBreakMode:UILineBreakModeWordWrap];
and also ";" is missing in label`
myLabel.text = #"About Stores";
myLabel.text = #"About Rivers";`
regards..
There's a difference because the system font is Helvetica, which is a variable-sized font. The text in myString1 is maginally wider than the text in myString2, so the string needs to wrap to a second line in order to fit. Since you specified 2 lines max and UILineBreakModeWordWrap, that's what you get. If you want it to fit in one line, make myLabelSize a little wider or else use a smaller font size.