Dynamically getting height of UILabel according to Text return different Value for iOS 7.0 and iOS 6.1

I am using the this method for getting the height of the UILabel Dynamically:

+(CGSize) GetSizeOfLabelForGivenText:(UILabel*)label Font:(UIFont*)fontForLabel Size:  (CGSize)LabelSize{
    label.numberOfLines = 0;
    CGSize labelSize = [label.text sizeWithFont:fontForLabel constrainedToSize:LabelSize lineBreakMode:NSLineBreakByCharWrapping];
    return (labelSize);
}

With this solution I am getting the exact size of UILabel if my code is running on below iOS 8 but if I run my application on iOS7 then it is returns a different value.


Solution 1:

You have to dynamically set the frame, like below:

Tested on iOS 6 to iOS 12.2

Swift:

let constrainedSize = CGSize(width: self.titleLable.frame.size.width, height:9999)

let attributesDictionary = [NSAttributedString.Key.font: UIFont.init(name: "HelveticaNeue", size: 11.0)]

let string = NSAttributedString.init(string: "textToShow", attributes: attributesDictionary as [NSAttributedString.Key : Any])

var requiredHeight = string.boundingRect(with: constrainedSize, options: .usesLineFragmentOrigin, context: nil)


if (requiredHeight.size.width > self.titleLable.frame.size.width) {
    requiredHeight = CGRect(x: 0, y: 0, width: self.titleLable.frame.size.width, height: requiredHeight.size.height)
}
var newFrame = self.titleLable.frame
newFrame.size.height = requiredHeight.size.height
self.titleLable.frame = newFrame

Objective C:

CGSize constrainedSize = CGSizeMake(self.resizableLable.frame.size.width  , 9999);

NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [UIFont fontWithName:@"HelveticaNeue" size:11.0], NSFontAttributeName,
                                      nil];

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"textToShow" attributes:attributesDictionary];

CGRect requiredHeight = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin context:nil];

if (requiredHeight.size.width > self.resizableLable.frame.size.width) {
    requiredHeight = CGRectMake(0,0, self.resizableLable.frame.size.width, requiredHeight.size.height);
}
CGRect newFrame = self.resizableLable.frame;
newFrame.size.height = requiredHeight.size.height;
self.resizableLable.frame = newFrame;

Solution 2:

Here's a total solution for width and height. Put these in your AppDelegate:

+(void)fixHeightOfThisLabel:(UILabel *)aLabel
{
    aLabel.frame = CGRectMake(aLabel.frame.origin.x,
                              aLabel.frame.origin.y,
                              aLabel.frame.size.width,
                              [AppDelegate heightOfTextForString:aLabel.text
                                                         andFont:aLabel.font
                                                         maxSize:CGSizeMake(aLabel.frame.size.width, MAXFLOAT)]);
}

+(CGFloat)heightOfTextForString:(NSString *)aString andFont:(UIFont *)aFont maxSize:(CGSize)aSize
{
    // iOS7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
        CGSize sizeOfText = [aString boundingRectWithSize: aSize
                                                  options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                               attributes: [NSDictionary dictionaryWithObject:aFont
                                                                                       forKey:NSFontAttributeName]
                                                  context: nil].size;

        return ceilf(sizeOfText.height);
    }

    // iOS6
    CGSize textSize = [aString sizeWithFont:aFont
                          constrainedToSize:aSize
                              lineBreakMode:NSLineBreakByWordWrapping];
    return ceilf(textSize.height;
}

+(void)fixWidthOfThisLabel:(UILabel *)aLabel
{
    aLabel.frame = CGRectMake(aLabel.frame.origin.x,
                              aLabel.frame.origin.y,
                                [AppDelegate widthOfTextForString:aLabel.text
                                                          andFont:aLabel.font
                                                          maxSize:CGSizeMake(MAXFLOAT, aLabel.frame.size.height)],
                              aLabel.frame.size.height);
}

+(CGFloat)widthOfTextForString:(NSString *)aString andFont:(UIFont *)aFont maxSize:(CGSize)aSize
{
    // iOS7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
        CGSize sizeOfText = [aString boundingRectWithSize: aSize
                                                  options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                               attributes: [NSDictionary dictionaryWithObject:aFont
                                                                                       forKey:NSFontAttributeName]
                                                  context: nil].size;

        return ceilf(sizeOfText.width);
    }

    // iOS6
    CGSize textSize = [aString sizeWithFont:aFont
                          constrainedToSize:aSize
                              lineBreakMode:NSLineBreakByWordWrapping];
    return ceilf(textSize.width);
}

then to use this, set the label's text:

label.numberOfLines = 0;
label.text = @"Everyone loves Stack OverFlow";

and call:

[AppDelegate fixHeightOfThisLabel:label];

Note: label's numberOfLines has to be set to 0. Hope that helps.