Adjust UILabel height depending on the text

2018-12-31 06:20发布

Consider I have the following text in a UILabel (a long line of dynamic text):

Since the alien army vastly outnumbers the team, players must use the post-apocalyptic world to their advantage, such as seeking cover behind dumpsters, pillars, cars, rubble, and other objects.

I want to resize the UILabel's height so that the text can fit in. I'm using following properties of UILabel to make the text within to wrap.

myUILabel.lineBreakMode = UILineBreakModeWordWrap;
myUILabel.numberOfLines = 0;

Please let me know if I'm not heading in the right direction. Thanks.

30条回答
萌妹纸的霸气范
2楼-- · 2018-12-31 06:56

Solution to iOS7 prior and iOS7 above

//
//  UILabel+DynamicHeight.m
//  For StackOverFlow
//
//  Created by Vijay on 24/02/14.
//  Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved.
//

#import <UIKit/UIKit.h>

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

#define iOS7_0 @"7.0"

@interface UILabel (DynamicHeight)

/*====================================================================*/

/* Calculate the size,bounds,frame of the Multi line Label */

/*====================================================================*/
/**
 *  Returns the size of the Label
 *
 *  @param aLabel To be used to calculte the height
 *
 *  @return size of the Label
 */

-(CGSize)sizeOfMultiLineLabel;

@end


//
//  UILabel+DynamicHeight.m
//  For StackOverFlow
//
//  Created by Vijay on 24/02/14.
//  Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved.
//

#import "UILabel+DynamicHeight.h"

@implementation UILabel (DynamicHeight)
/*====================================================================*/

/* Calculate the size,bounds,frame of the Multi line Label */

/*====================================================================*/
/**
 *  Returns the size of the Label
 *
 *  @param aLabel To be used to calculte the height
 *
 *  @return size of the Label
 */
-(CGSize)sizeOfMultiLineLabel{

    NSAssert(self, @"UILabel was nil");

    //Label text
    NSString *aLabelTextString = [self text];

    //Label font
    UIFont *aLabelFont = [self font];

    //Width of the Label
    CGFloat aLabelSizeWidth = self.frame.size.width;


    if (SYSTEM_VERSION_LESS_THAN(iOS7_0)) {
        //version < 7.0

        return [aLabelTextString sizeWithFont:aLabelFont
                            constrainedToSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
                                lineBreakMode:NSLineBreakByWordWrapping];
    }
    else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(iOS7_0)) {
        //version >= 7.0

        //Return the calculated size of the Label
        return [aLabelTextString boundingRectWithSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : aLabelFont
                                                        }
                                              context:nil].size;

    }

    return [self bounds].size;

}

@end
查看更多
何处买醉
3楼-- · 2018-12-31 06:56

One line is Chris's answer is wrong.

newFrame.size.height = maximumLabelSize.height;

should be

newFrame.size.height = expectedLabelSize.height;

Other than that, it's the correct solution.

查看更多
怪性笑人.
4楼-- · 2018-12-31 06:58

Updated Method

+ (CGFloat)heightForText:(NSString*)text font:(UIFont*)font withinWidth:(CGFloat)width {

    CGSize constraint = CGSizeMake(width, 20000.0f);
    CGSize size;

    CGSize boundingBox = [text boundingRectWithSize:constraint
                                                  options:NSStringDrawingUsesLineFragmentOrigin
                                               attributes:@{NSFontAttributeName:font}
                                                  context:nil].size;

    size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));

    return size.height;
}
查看更多
心情的温度
5楼-- · 2018-12-31 06:58

Adding to the above answers:

This can be easily achieved via storyboard.

  1. Set constraint for UILabel.(In my case I did top, left and fixed width)
  2. Set Number of line to 0 in Attribute Inspector
  3. Set Line Break to WordWrap in Attribute Inspector.

UILabel Height Adjust

查看更多
无与为乐者.
6楼-- · 2018-12-31 06:59

The easiest and better way that worked for me was to apply height constraint to label and set the priority to low, i.e., (250) in storyboard.

So you need not worry about calculating the height and width programmatically, thanks to storyboard.

查看更多
何处买醉
7楼-- · 2018-12-31 07:00

Instead doing this programmatically, you can do this in Storyboard/XIB while designing.

  • Set UIlabel's number of lines property to 0 in attribute inspector.
  • Then set width constraint/(or) leading and trailing constraint as per the requirement.
  • Then set height constraint with minimum value. Finally select the height constraint you added and in the size inspector the one next to attribute inspector, change the height constraint's relation from equal to - greater than.
查看更多
登录 后发表回答