NSLineBreakByWordWrapping not working if word is too long - ios

Hi i am trying to resize string according to the text inside. But if the text (1 word text like link) is too long for the width that i used to resize it like below; label not fits it's size. The code that i am using is;
UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:14];
gettingSizeLabel.text = messageData.TEXT;
gettingSizeLabel.numberOfLines = 0;
gettingSizeLabel.lineBreakMode = NSLineBreakByWordWrapping | NSLineBreakByTruncatingTail;
CGSize maximumLabelSize = CGSizeMake(240, 9999);
CGSize expectSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];
As I write i want to resize text width to 240 (max), also it needs to be multiple lines. But the result can be calculated more than 240.
Thanks

This line is illegal:
gettingSizeLabel.lineBreakMode = NSLineBreakByWordWrapping | NSLineBreakByTruncatingTail;
lineBreakMode is not a bitmask. I'm surprised this would even compile, but the fact that it does is a good reason to switch to Swift, where this mistake is impossible to make.
If you fix that, it works fine (this is Swift, but it won't give you any trouble):
let s = "https://test.mobiletest.com/apps/12345678/install/abc123abc123abc123abc124"
let lab = UILabel()
lab.numberOfLines = 0
lab.text = s
lab.lineBreakMode = .ByWordWrapping
let result = lab.sizeThatFits(CGSizeMake(240,10000))
// (232.666666666667, 61.0)

Related

MultiLine UIlabel doesn't show all text?

I want to show label size as per text in it for that I have used
uilabel number of line property.
lbl.numberoflines = 0;
but it shows only three line and after that it shows ... . not all text showing.
when I will give number of line more than 3 then it showing that line in label.
appreciate for help
try this
lbl.lineBreakMode = UILineBreakModeWordWrap;
lbl.numberOfLines = 0;
if you want to manually calculate the height
lbl.numberOfLines = 0; // allows label to have as many lines as needed
lbl.text =#"xxxxxxxxxxxxxxxxxxxxxx";
CGSize labelSize = [ lbl.text sizeWithFont: lbl.font constrainedToSize:CGSizeMake(300, 300) lineBreakMode:NSLineBreakByWordWrapping];
// set the frame of labels here
else you can directly placed in Attribute
swift3
lbl.lineBreakMode = .byWordWrapping
lbl.numberOfLines = 0
// allows label to have as many lines as needed
lbl.text = "xxxxxxxxxxxxxxxxxxxxxx"
var labelSize = lbl.text.size(with: lbl.font, constrainedToSize: CGSize(width: 300, height: 300), lineBreakMode: .byWordWrapping)
// set the frame of labels here }
So I had made numberOfLines as 0 and had given lineBreakMode as WordWrap and had given proper constraints too.
What worked was changing the preferred width setting to automatic from explicit. i.e. from this:-
to this:-
try this
lbl.lineBreakMode = UILineBreakModeWordWrap;
lbl.numberOfLines = 0;
[lbl sizeTofit];
Use this method. May Help
-(CGSize)getLabelSize:(NSString *)text
{
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:14.0];
CGSize constraintSize = CGSizeMake(300.0f, MAXFLOAT);
CGSize labelSize = [text sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
return labelSize;
}
All answers may helpful. but uses old approach.
can't you add Constraint to your view ?
It will be really easy to set layout constraint, and then you go.

How to add NSString to view in define size rectangle

I need to add a sentence into my view. But the sentence is quite big. So i would like to put it inside a defined CGRect, with several lines, and change the font size, that all sentence will be visible in this CGRect. And the font size should be as big as it is possible.
Here the code that i am using:
NSAttributedString *sentence = [[NSAttributedString alloc] initWithString:#"The sentence with some words" attributes:#{NSFontAttributeName: wordsFont,NSBackgroundColorAttributeName:[UIColor yellowColor]}];
CGRect sentenceBounds;
sentenceBounds.size = [sentence size];
CGSize neededSize = CGSizeMake(MAX_WIDTH, MAX_HAIGHT);
sentenceBounds.size = neededSize;
sentenceBounds.origin = CGPointMake(0, 0);
[sentence drawInRect:sentenceBounds];
All of the functionality you're looking for is included with UILabel. Is there a reason you can't just use that?
UILabel *label = [UILabel new];
label.adjustsFontSizeToFitWidth = YES;
label.numberOfLines = 0;
label.attributedText = sentence;
label.frame = CGRectZero; //set desired frame here;
[self addSubview:label];

UILabel with "+" text not centered vertically

self.iconLabel.frame = self.contentView.frame;
self.iconLabel.font = [UIFont systemFontOfSize:100.0];
self.iconLabel.text = #"+";
self.iconLabel.textColor = [UIColor blackColor];
self.iconLabel.textAlignment = NSTextAlignmentCenter;
So the UILabel's frame is the same size as its container view, self.contentView
I need the "+" to be centered vertically also, I want it in the center.
How can I achieve this?
My only notion is to shift the iconLabel.frame up.
EDIT: Changed from self.iconImageView to self.contentView which is a UIView. The UILabel is layered above the self.iconImageView which is a UIImageView.
EDIT 2: Tried implementing kshitij godara's code, the result is:
I altered the code slightly:
CGSize constraint = CGSizeMake(self.contentView.frame.size.width, self.contentView.frame.size.height);
NSString *str = #"+";
UIFont *myFont = [UIFont systemFontOfSize:100.0];
CGSize stringSize = [str sizeWithFont:myFont constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
self.iconLabel.frame = CGRectMake(0, 0, stringSize.width, stringSize.height);
self.iconLabel.font = myFont;
self.iconLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.iconLabel.numberOfLines = 0;
[self.iconLabel sizeToFit];
self.iconLabel.text = str;
EDIT 3:
the frame is quite large:
This is probably a problem of the font itself. Each font has defined it shapes, behavior, typesetting etc. The font seems to be positioning character "+" of the visual vertical center. You can test it on any other string containing letter "+", "dog+Cat" for example. The "+" letter will probably be drawn near bottom as it is on your image.
From my point of view, you have 2 options:
Use icon image instead for the "+" sign. This will be simplest and the best working solution
Use custom font edited to visually look exactly like you need (letter "+" totally centered in its typeset). This one would probably be very painfull and time-consuming option
Edit: Regarding 2nd option: I have already done such an procedure to fix some misaligned fonts following this tutorial. However it still just fixes the whole font, not on a single character basis
You can do this -- Try to apply this
CGSize constraint = CGSizeMake(iconImageFrame.size.width,1000.0f);
//Now Calculate size of string
NSString *str = #"+";
//Always give the same font to calculate size which you giving for label
UIFont *myFont = [UIFont systemFontOfSize:100.0];
CGSize stringSize = [str sizeWithFont:myFont
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
//now set same font for uilabel and also make it to fit to size
//like this
UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(myIconLabelFrame.x,myIconLabelFrame.y,stringSize.width,stringSize.height)];
myLabel.font = myFont;
myLabel.lineBreakMode = UILineBreakModeWordWrap;
myLabel.numberOfLines = 0;
[myLabelsizeToFit];
myLabel.text = str;
As now label will be completely fit in size , therefore it will always be in center .This code also can be used for to increase height of label dynamically .
I hope it solve your problem .Thanks!

iOS, how to draw the dynamic length of text?

The picture is: http://www.flickr.com/photos/71607441#N07/6641626163/
The background is a UIImageView, and the blue part I want to show as "title" of the image.
I used UILabel, but the length of the text is dynamic. It can be one line or two line, at most two line. If the text is longer than two lines, it will be truncated.
The blue part looks like "highlight in Microsoft Word", but it is not "highlight in iOS UILabel.text"
Is there anyone can help me?
Try this code :----
CGSize maximumSize = CGSizeMake(320, 30);
UILabel *newsLabel = [[UILabel alloc] init];
newsLabel.textColor = [UIColor whiteColor];
newsLabel.font = [UIFont boldSystemFontOfSize:11];
newsLabel.backgroundColor = [UIColor clearColor];
newsLabel.lineBreakMode = UILineBreakModeWordWrap;
newsLabel.numberOfLines = 0;
lineBreakMode:newsLabel.lineBreakMode];
CGSize dateStringSize = [#"Text Input" sizeWithFont:newsLabel.font
constrainedToSize:maximumSize
lineBreakMode:newsLabel.lineBreakMode];
CGRect dateFrame = CGRectMake(5, 5, 320, dateStringSize.height); //breath can be any desired float value
newsLabel.text = #"Text Input";
newsLabel.textAlignment = UITextAlignmentCenter;
newsLabel.frame = dateFrame;
You can find the size in pixels required for your title using:
CGSize size = [UILabel.text sizeWithFont:yourFont];
there's also:
CGSize size = [UILabel.text sizeWithFont:yourFont lineBreakMode: yourLineBreakMode];
You could then use these dimensions (size.width, size.height) to set the frame of your UILabel.
Hope this helps. :)

Multiple lines of text in UILabel

Is there a way to have multiple lines of text in UILabel like in the UITextView or should I use the second one instead?
Set the line break mode to word-wrapping and the number of lines to 0:
// Swift
textLabel.lineBreakMode = .byWordWrapping
textLabel.numberOfLines = 0
// Objective-C
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.numberOfLines = 0;
// C# (Xamarin.iOS)
textLabel.LineBreakMode = UILineBreakMode.WordWrap;
textLabel.Lines = 0;
Restored old answer (for reference and devs willing to support iOS below 6.0):
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.numberOfLines = 0;
On the side: both enum values yield to 0 anyway.
In IB, set number of lines to 0 (allows unlimited lines)
When typing within the text field using IB, use "alt-return" to insert a return and go to the next line (or you can copy in text already separated out by lines).
The best solution I have found (to an otherwise frustrating problem that should have been solved in the framework) is similar to vaychick's.
Just set number of lines to 0 in either IB or code
myLabel.numberOfLines = 0;
This will display the lines needed but will reposition the label so its centered horizontally (so that a 1 line and 3 line label are aligned in their horizontal position). To fix that add:
CGRect currentFrame = myLabel.frame;
CGSize max = CGSizeMake(myLabel.frame.size.width, 500);
CGSize expected = [myString sizeWithFont:myLabel.font constrainedToSize:max lineBreakMode:myLabel.lineBreakMode];
currentFrame.size.height = expected.height;
myLabel.frame = currentFrame;
Use this to have multiple lines of text in UILabel:
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.numberOfLines = 0;
Swift:
textLabel.lineBreakMode = .byWordWrapping
textLabel.numberOfLines = 0
myUILabel.numberOfLines = 0;
myUILabel.text = #"your long string here";
[myUILabel sizeToFit];
If you have to use the:
myLabel.numberOfLines = 0;
property you can also use a standard line break ("\n"), in code, to force a new line.
You can use \r to go to next line while filling up the UILabel using NSString.
UILabel * label;
label.text = [NSString stringWithFormat:#"%# \r %#",#"first line",#"seconcd line"];
lets try this
textLabel.lineBreakMode = NSLineBreakModeWordWrap; // UILineBreakModeWordWrap deprecated
textLabel.numberOfLines = 0;
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.numberOfLines = 0;
The solution above does't work in my case. I'm doing like this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// ...
CGSize size = [str sizeWithFont:[UIFont fontWithName:#"Georgia-Bold" size:18.0] constrainedToSize:CGSizeMake(240.0, 480.0) lineBreakMode:UILineBreakModeWordWrap];
return size.height + 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
// ...
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Georgia-Bold" size:18.0];
}
// ...
UILabel *textLabel = [cell textLabel];
CGSize size = [text sizeWithFont:[UIFont fontWithName:#"Georgia-Bold" size:18.0]
constrainedToSize:CGSizeMake(240.0, 480.0)
lineBreakMode:UILineBreakModeWordWrap];
cell.textLabel.frame = CGRectMake(0, 0, size.width + 20, size.height + 20);
//...
}
Swift 3
Set number of lines zero for dynamic text information, it will be useful for varying text.
var label = UILabel()
let stringValue = "A label\nwith\nmultiline text."
label.text = stringValue
label.numberOfLines = 0
label.lineBreakMode = .byTruncatingTail // or .byWrappingWord
label.minimumScaleFactor = 0.8 . // It is not required but nice to have a minimum scale factor to fit text into label frame
Use story borad : select the label to set number of lines to zero......Or Refer this
Try using this:
lblName.numberOfLines = 0;
[lblName sizeToFit];
UILabel *helpLabel = [[UILabel alloc] init];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:label];
helpLabel.attributedText = attrString;
// helpLabel.text = label;
helpLabel.textAlignment = NSTextAlignmentCenter;
helpLabel.lineBreakMode = NSLineBreakByWordWrapping;
helpLabel.numberOfLines = 0;
For some reasons its not working for me in iOS 6 not sure why. Tried it with and without attributed text. Any suggestions.
Method 1:
extension UILabel {//Write this extension after close brackets of your class
func lblFunction() {
numberOfLines = 0
lineBreakMode = .byWordWrapping//If you want word wraping
//OR
lineBreakMode = .byCharWrapping//If you want character wraping
}
}
Now call simply like this
myLbl.lblFunction()//Replace your label name
EX:
Import UIKit
class MyClassName: UIViewController {//For example this is your class.
override func viewDidLoad() {
super.viewDidLoad()
myLbl.lblFunction()//Replace your label name
}
}//After close of your class write this extension.
extension UILabel {//Write this extension after close brackets of your class
func lblFunction() {
numberOfLines = 0
lineBreakMode = .byWordWrapping//If you want word wraping
//OR
lineBreakMode = .byCharWrapping//If you want character wraping
}
}
Method 2:
Programmatically
yourLabel.numberOfLines = 0
yourLabel.lineBreakMode = .byWordWrapping//If you want word wraping
//OR
yourLabel.lineBreakMode = .byCharWrapping//If you want character wraping
Method 3:
Through Story board
To display multiple lines set 0(Zero), this will display more than one line in your label.
If you want to display n lines, set n.
See below screen.
If you want to set minimum font size for label Click Autoshrink and Select Minimum Font Size option
See below screens
Here set minimum font size
EX: 9 (In this image)
If your label get more text at that time your label text will be shrink upto 9
These things helped me
Change these properties of UILabel
label.numberOfLines = 0;
label.adjustsFontSizeToFitWidth = NO;
label.lineBreakMode = NSLineBreakByWordWrapping;
And while giving input String use \n to display different words in different lines.
Example :
NSString *message = #"This \n is \n a demo \n message for \n stackoverflow" ;
Swift 4:
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.preferredMaxLayoutWidth = superview.bounds.size.width - 10
UILabel *labelName = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
[labelName sizeToFit];
labelName.numberOfLines = 0;
labelName.text = #"Your String...";
[self.view addSubview:labelName];
You can do that via the Storyboard too:
Select the Label on the view controller
In the Attribute Inspector, increase the value of the Line option (Press Alt+Cmd+4 to show Attributes Inspector)
Double click the Label in the view controller and write or paste your text
Resize the Label and/or increase the font size so that the whole text could be shown
you should try this:
-(CGFloat)dynamicLblHeight:(UILabel *)lbl
{
CGFloat lblWidth = lbl.frame.size.width;
CGRect lblTextSize = [lbl.text boundingRectWithSize:CGSizeMake(lblWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:lbl.font}
context:nil];
return lblTextSize.size.height;
}
Oh, in 2021 I'm trapped by a label text unable to change lines for 1 hour, then realize I forget to set label's width, WTF.
let stepLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0
label.text = "Put your device and computer under same Wi-Fi network."
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(stepLabel)
NSLayoutConstraint.activate([
stepLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stepLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
stepLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.7)
])
}
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 150, 30)];
[textLabel sizeToFit];
textLabel.numberOfLines = 0;
textLabel.text = #"Your String...";
Already answered, but you can do it manually in the storyboard too. Under Attributes Inspector for the Label, you can change Line Breaks to Word Wrap (or character wrap).
In this function pass string that you want to assign in label and pass font size in place of self.activityFont and pass label width in place of 235, now you get label height according to your string.
it will work fine.
-(float)calculateLabelStringHeight:(NSString *)answer
{
CGRect textRect = [answer boundingRectWithSize: CGSizeMake(235, 10000000) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:self.activityFont} context:nil];
return textRect.size.height;
}
Set below either in code or in storyboard itself
Label.lineBreakMode = NSLineBreakByWordWrapping;
Label.numberOfLines = 0;
and please don't forget to set left, right, top and bottom constraints for label otherwise it won't work.
On C#, this worked for me inside UITableViewCell.
UILabel myLabel = new UILabel();
myLabel.Font = UIFont.SystemFontOfSize(16);
myLabel.Lines = 0;
myLabel.TextAlignment = UITextAlignment.Left;
myLabel.LineBreakMode = UILineBreakMode.WordWrap;
myLabel.MinimumScaleFactor = 1;
myLabel.AdjustsFontSizeToFitWidth = true;
myLabel.InvalidateIntrinsicContentSize();
myLabel.Frame = new CoreGraphics.CGRect(20, mycell.ContentView.Frame.Y + 20, cell.ContentView.Frame.Size.Width - 40, mycell.ContentView.Frame.Size.Height);
myCell.ContentView.AddSubview(myLabel);
I think the point here is:-
myLabel.TextAlignment = UITextAlignment.Left;
myLabel.LineBreakMode = UILineBreakMode.WordWrap;
myLabel.MinimumScaleFactor = 1;
myLabel.AdjustsFontSizeToFitWidth = true;
This code is returning size height according to text
+ (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font
{
CGFloat result = font.pointSize+4;
if (text)
{
CGSize size;
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, 999)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:font}
context:nil];
size = CGSizeMake(frame.size.width, frame.size.height+1);
result = MAX(size.height, result); //At least one row
}
return result;
}

Resources