Calculating number of lines of dynamic UILabel (iOS7)
Asked Answered
S

7

8

There are many solutions to this questions arround but couldn't find non-deprecated one.

I have an UILabel with mode WordWrap and fixed width of, let's say 250. Lines are set to 0.

Here is what I tried:

UILabel *contentLabel = (UILabel*)[contentView viewWithTag:10];
CGSize size = [contentLabel.text sizeWithFont:contentLabel.font forWidth:contentLabel.frame.size.width lineBreakMode:NSLineBreakByWordWrapping];
NSLog(@"Label's height is: %d", size.height);

The output of height param is always 20 (so it's like one line), while te text is like 30 lines long.

I need that for UIScrollView purposes.

Steatite answered 13/9, 2013 at 10:33 Comment(5)
If above answer is yes then please try this [contentLabel sizeToFit]; Hope This will solve your issue.Malta
There is no mention of using UITableView.Marinemarinelli
sorry..thanks for making it noticed to me..have you tried this [contentLabel sizeToFit];Malta
Beacause in your code you have wrote forWidth , it should be constrainedToSizeProtest
Cmd + click on sizeWithFont:forWidth:lineBreakMode: and you see new method suggested to use instead of deprecated one. Also you can use pre-release documentation to figure out details.Reinhardt
R
55

Use suggested in documentation method :

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(7_0);

E.g.

    CGSize maxSize = CGSizeMake(self.label.frame.size.width, MAXFLOAT);

    CGRect labelRect = [self.label.text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.label.font} context:nil];

    NSLog(@"size %@", NSStringFromCGSize(labelRect.size));
Reinhardt answered 13/9, 2013 at 11:31 Comment(5)
Don't forget to ceil the width and height; ceil(labelRect.size.width);Cadmus
But this one only return the height of one line. How does it work for multiple lines?Latinalatinate
@bagusflyer see my answer for how I worked around the single line height resultHypocycloid
How can you find the number of lines from this??Dissatisfactory
this is working , but in order to calculate the height of multiple lines add : [label sizeToFit];Pinder
H
4

I was having trouble using boundingRectWithSize directly on my UILabel's attributedText — it was not accounting for the wrap to multiple lines, (the returned height was always 17.5). To work around this, I had to use boundingRectWithSize on the UILabel's text property and pass in the attributes dictionary separately (and not via [self.myLabel.attributedText attributesAtIndex:0 effectiveRange:nil]).

CGRect labelSize = CGRectIntegral([self.myLabel.text     
    boundingRectWithSize:CGSizeMake(self.myLabel.frame.size.width, MAXFLOAT) 
    options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
    attributes:@{NSFontAttributeName:self.myLabel.font, 
    NSParagraphStyleAttributeName:paragraphStyle} context:nil]);
Hypocycloid answered 29/1, 2015 at 22:44 Comment(4)
What if I am using autolayout and the self.myLabel.frame is not yet calculated?Supremacy
I believe this post is relevant to the question, although it doesn't answer itLiveryman
@VladimírSlavík you should call this code only when frame is already known; Can't do it any other way I'm afraid. Call this functionality at appropriate time, such as viewDidLoad etcLiveryman
This is so stupid. I've been fussing with this exact problem for hours. Why on earth wouldn't the existing attributes work?Farant
F
1

You can use this simple method:

which will return number of lines

- (int)lineCountForLabel:(UILabel *)label
{
    CGFloat labelWidth = label.frame.size.width;
    int lineCount = 0;
    CGSize textSize = CGSizeMake(labelWidth, MAXFLOAT);
    long rHeight = lroundf([label sizeThatFits:textSize].height);
    long charSize = lroundf(label.font.leading);
    lineCount = (int)( rHeight / charSize );
    return lineCount;
}

by calling

[self lineCountForLabel:YOUR_LABEL];
Fritillary answered 20/7, 2015 at 10:49 Comment(0)
M
0
     let l = UILabel()

        l.numberOfLines = 0


        l.layer.frame.size.width = self.view.frame.width - 40 /*(Padding 20 + 20)*/
        l.font = UIFont(name: "BwModelica-Bold", size: 16.0)

        l.text = "Your Any length Text!!"

        let noOfLines = ceil(l.intrinsicContentSize.width) / l.frame.width

        let lbl_height = noOfLines * l.intrinsicContentSize.height

This will be your Exact dynamic height of Label. Happy coding!!!

Meddlesome answered 18/1, 2019 at 7:46 Comment(0)
H
0

This has worked for me:

*Set the numberOfLines property of UILabel to 0 *add this line: yourLabel.sizeToFit() after assigning text to the UILabel

Histoid answered 29/5, 2021 at 17:12 Comment(0)
S
-3

Try this out

//Here tweetText is an object of NSString and assign a text to it  
NSString *tweetText = tweet.tweetText;
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

CGSize size = [tweetText sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];

//detailLabel is an object of UILabel    
[detailLabel setText:tweetText];

//Set frame
[detailLabel setFrame:CGRectMake(76,20,280, MAX(size.height, 30.0f))];
Supraliminal answered 13/9, 2013 at 11:1 Comment(2)
sizeWithFont is deprecate. OP wanted non-deprecated solution.Timotheus
In iOS 7,you can use boundingRectWithSize: instead sizeWithFont:.Supraliminal
B
-6

Here is method which I'm using:

CGSize maximumSize = CGSizeMake(contentLabel.frame.size.width, 9999);

CGSize myStringSize = [eventName sizeWithFont:contentLabel.font
                            constrainedToSize:maximumSize
                                lineBreakMode:UILineBreakModeWordWrap];
Buckish answered 13/9, 2013 at 10:51 Comment(2)
UILineBreakModeWordWrap is deprecrecated use NSLineBreakByWordWrappingBuckish
In iOS 7, sizeWithFont:... is deprecated as well. Use boundingRectWithSize:... instead.Straightforward

© 2022 - 2024 — McMap. All rights reserved.