4

I have an UILabel with fixed size, the text that I set into this UILabel can be 200, 5 or 500 characters long. What I want to do is to calculate how much visible text can I put into this UILabel with the current UILabel size.

Why I want to do that? Because I want to add a ...Read more text at the end of the text, but not at the end of the whole text, just at the end of the visible text in the UILabel.

Thanks in advance.

ytpm
  • 4,962
  • 6
  • 56
  • 113

4 Answers4

5

So I've created a method which returns the current visible string height (with the size of the UITextView / UITextField or UILabel) and it's also support iOS6+, this is what I did:

- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
{
    UIFont *font           = label.font;
    NSLineBreakMode mode   = label.lineBreakMode;

    CGFloat labelWidth     = label.frame.size.width;
    CGFloat labelHeight    = label.frame.size.height;
    CGSize  sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);

    if (SYSTEM_VERSION_GREATER_THAN(iOS_7))
    {
        NSDictionary *attributes = @{ NSFontAttributeName : font };
        NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:string attributes:attributes];
        CGRect boundingRect = [attributedText boundingRectWithSize:sizeConstraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
        {
            if (boundingRect.size.height > labelHeight)
            {
                NSUInteger index = 0;
                NSUInteger prev;
                NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];

                do
                {
                    prev = index;
                    if (mode == NSLineBreakByCharWrapping)
                        index++;
                    else
                        index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location;
                }

                while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] boundingRectWithSize:sizeConstraint options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size.height <= labelHeight);

                return prev;
            }
        }
    }
    else
    {
        if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
        {
            NSUInteger index = 0;
            NSUInteger prev;
            NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];

            do
            {
                prev = index;
                if (mode == NSLineBreakByCharWrapping)
                    index++;
                else
                    index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location;
            }

            while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height <= labelHeight);

            return prev;
        }
    }

    return [string length];
}

Of course that SYSTEM_VERSION_GREATER_THAN(iOS_7) are both macros that I defined. You also should define your own.

Best of luck!

ytpm
  • 4,962
  • 6
  • 56
  • 113
0

You can set a fixed number of characters followed by:

CGSize size = [string sizeWithFont:font 
                 constrainedToSize:sizeConstraint 
                     lineBreakMode:UILineBreakModeWordWrap]; 

and find out how much the CGSize of the UILabel would be according to the text length of a particular font and append. Read more to a fixed number of characters. The reason for this turn around is that there is no native way of finding out the number of visible characters in a label before truncating.

Alex Cio
  • 6,014
  • 5
  • 44
  • 74
Saheb Roy
  • 5,899
  • 3
  • 23
  • 35
0

This one works for me, hope it helps you too,

- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
{
    UIFont *font           = label.font;
    NSLineBreakMode mode   = label.lineBreakMode;

    CGFloat labelWidth     = label.frame.size.width;
    CGFloat labelHeight    = label.frame.size.height;
    CGSize  sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);


    NSDictionary *attributes = @{ NSFontAttributeName : font };
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:string attributes:attributes];
    CGRect boundingRect = [attributedText boundingRectWithSize:sizeConstraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
    {
        if (boundingRect.size.height > labelHeight)
        {
            NSUInteger index = 0;
            NSUInteger prev;
            NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];

            do
            {
                prev = index;
                if (mode == NSLineBreakByCharWrapping)
                    index++;
                else
                    index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location;
            }

            while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] boundingRectWithSize:sizeConstraint options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size.height <= labelHeight);

            return prev;
        }
    }


    return [string length];
 }
Patel Jigar
  • 2,141
  • 1
  • 23
  • 30
-1

Try using below method in UILabel

Set Your Text Like this

Add your text in string like :-> lbl.text=@"abcdeedjedaekd.....Read more."

its an Idea not proper solution, but may be helpful to you

Pawan Rai
  • 3,434
  • 4
  • 32
  • 42
Mehul
  • 3,033
  • 23
  • 37