根据Text动态获取UILabel的高度为iOS 7.0和iOS 6.1返回不同的值

时间:2013-11-19 10:19:56

标签: ios iphone objective-c ios6 ios7

我正在使用此方法动态获取UILabel的高度:

+(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);
}

使用此解决方案,如果我的代码在iOS 8下运行,我将获得UILabel的确切大小 但如果我在iOS7上运行我的应用程序,那么它将返回一个不同的值。

13 个答案:

答案 0 :(得分:26)

您必须动态设置框架,如下所示:

//Compatible for both ios6 and ios7.  

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;

答案 1 :(得分:5)

这是宽度和高度的完整解决方案。把它们放在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);
}

然后使用它,设置标签的文本:

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

并致电:

[AppDelegate fixHeightOfThisLabel:label];

注意:label的numberOfLines必须设置为0。 希望有所帮助。

答案 2 :(得分:4)

如果您使用的是任何系统字体,则它们会在iOS 7中更改,因此它们的大小会有所不同。


此外,在iOS 7中不推荐使用sizeWithFont:constrainedToSize:lineBreakMode:。请改用sizeWithAttributes:(如果您使用的是iOS 7)

答案 3 :(得分:2)

接受的答案不满足我,所以我不得不在我的代码中挖掘它:

CGSize possibleSize = [string sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:10] //font you are using
                          constrainedToSize:CGSizeMake(skillsMessage.frame.size.width,9999)
                              lineBreakMode:NSLineBreakByWordWrapping];


CGRect newFrame = label.frame;
newFrame.size.height = possibleSize.height;
label.frame = newFrame;

答案 4 :(得分:1)

接受的答案太长了。您可以使用以下内容:

+(CGSize) GetSizeOfLabelForGivenText:(UILabel*)label Font:(UIFont*)fontForLabel Size:  (CGSize) constraintSize{
    label.numberOfLines = 0;
    CGRect labelRect = [label.text boundingRectWithSize:constraintSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName:fontForLabel} context:nil];
    return (labelRect.size);
}

答案 5 :(得分:1)

我一直使用sizeThatFits:

CGRect frame = myLabel.frame;
CGSize constraint = CGSizeMake(CGRectGetWidth(myLabel.frame), 20000.0f);
CGSize size = [myLabel sizeThatFits:constraint];
frame.size.height = size.height;
myLabel.frame = frame;

你可以试试这个

答案 6 :(得分:0)

无论我通过此代码得到什么高度(我在上面的这个问题中写过的方法)。它提供浮动值(86.4)的高度,一旦我们得到它并尝试设置该高度到UILabel,但我们需要从ceil (87)获取高度值而不是值(86.4)。我用这种方法解决了我的问题。谢谢你的回答。

答案 7 :(得分:0)

这是我最后提出的,希望这会对你有所帮助。我检查了iOS版本,就像Apple本身在iOS 7 UI Transition Guide中所做的那样,其中包括检查Foundation Framework版本并使用#pragma来抑制Deprecated:使用" - (CGSize)sizeWithFont来抑制iOS 7或更高版本的警告: (UIFont *)font constrainedToSize:(CGSize)size"。

+ (CGSize)getStringBoundingSize:(NSString*)string forWidth:(CGFloat)width withFont:(UIFont*)font{

    CGSize maxSize = CGSizeMake(width, CGFLOAT_MAX);
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
        // for iOS 6.1 or earlier
        // temporarily suppress the warning and then turn it back on
        // since sizeWithFont:constrainedToSize: deprecated on iOS 7 or later
        #pragma clang diagnostic push
        #pragma clang diagnostic ignored "-Wdeprecated-declarations"
            maxSize = [string sizeWithFont:font constrainedToSize:maxSize];
        #pragma clang diagnostic pop

    } else {
        // for iOS 7 or later
        maxSize = [string sizeWithAttributes:@{NSFontAttributeName:font}];

    }
    return maxSize;
}

答案 8 :(得分:0)

iOS7中不推荐使用方法sizeWithFont:constrainedToSize:lineBreakMode:。 您应该使用sizeWithAttributes:代替。

示例:

NSDictionary *fontAttributes = @{NSFontAttributeName : [UIFont systemFontOfSize:15]};
CGSize textSize = [self.myLabel.text sizeWithAttributes:fontAttributes];
CGFloat textWidth = textSize.width;
CGFloat textHeight = textSize.height;

答案 9 :(得分:0)

超级简单。只需获取文本区域,除以宽度,然后向上舍入到最接近您的字体的高度。

+ (CGFloat)heightForText:(NSString*)text font:(UIFont*)font withinWidth:(CGFloat)width {
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName:font}];
    CGFloat area = size.height * size.width;
    CGFloat height = roundf(area / width);
    return ceilf(height / font.lineHeight) * font.lineHeight;
}

非常即插即用的解决方案。我在辅助类中经常使用它,特别是对于动态大小的UITableViewCells。

希望这有助于将来的其他人!

答案 10 :(得分:0)

我有一种情况需要根据文本动态设置标签的高度。我正在使用Xcode 7.1,我的项目部署目标是7.0,但我在iOS 9模拟器上测试它,以下解决方案适合我。这是解决方案: 首先,您将创建一个这样的字典:

#plot picker

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np

class SelectPoint(object):


   def __init__(self, ax, collection, colorother='#ffffff'):
    self.canvas = ax.figure.canvas
    self.collection = collection
    self.colorother = colorother
    self.colorbyitem=colorbyitem
    self.canvas.mpl_connect('pick_event', self.on_pick)

   def on_pick(self, event):
    self.thisparticle=event.artist

    self.label=self.thisparticle.get_label()
    self.index=event.ind[0]
    print self.index
    print self.colorbyitem[self.label][self.index]
    self.colorbyitem[self.label][self.index]='#ff8000'
    self.collection.set_color(self.colorbyitem[self.label])
    self.collection.set_edgecolor('#000000')
    self.canvas.draw_idle()

colors=['#0000ff','#0000ff','#0000ff','#0000ff','#0000ff']
colors1=['#00ffff','#00ffff','#00ffff','#00ffff','#00ffff']

x1=[1,2,3,4,5]
y1=[1,2,3,4,5]
x1=np.array(x1)
y1=np.array(y1)
colors=np.array(colors)
colors1=np.array(colors1)


colorbyitem={}


item='23532_10'
item2='23555_04'
colorbyitem[item]=colors
colorbyitem[item2]=colors1


x=[1,2,3,4,5]
y=[1,2,3,4,5]
x=np.array(x)
y=np.array(y)

subplot_kw = dict(xlim=(0, 5), ylim=(0, 5), autoscale_on=False)

fig5v4, ax=plt.subplots(subplot_kw=subplot_kw)
fig5v6, ax1=plt.subplots(subplot_kw=subplot_kw)

coll=ax.scatter(x,y, c=colors, s=75, picker=1, label=item)
coll1=ax1.scatter(x1, y1, c=colors, s=75, picker=1, label=item)

coll3=ax.scatter(1.1*y, .9*x, c=colors1, s=75, picker=1, label=item2)

coll4=ax1.scatter(1.1*y, .9*x, c=colors1, s=75, picker=1, label=item2)


selector=SelectPoint(ax, coll)
selector2=SelectPoint(ax1, coll1)   

selector3=SelectPoint(ax, coll3)
selector4=SelectPoint(ax1, coll4)
plt.show()

raw_input()

现在我们将计算文本的高度和宽度,并传递新创建的字典。

NSDictionary *attributes = @{NSFontAttributeName:self.YOUR_LABEL.font};

然后我们将设置LABEL的框架:

    CGRect rect = [YOUR_TEXT_STRING boundingRectWithSize:CGSizeMake(LABEL_WIDTH, CGFLOAT_MAX)
                                          options:NSStringDrawingUsesLineFragmentOrigin
                                       attributes:attributes
                                          context:nil];

这就是我如何根据文字成功设置我的标签框架。

答案 11 :(得分:0)

我从iOS 7到iOS 11.4使用和测试了这个方法

+ (CGFloat)getLabelHeight:(UILabel*)label
{
    NSParameterAssert(label);
    CGSize limitLabel = CGSizeMake(label.frame.size.width, CGFLOAT_MAX);
    CGSize size;

    NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
    CGSize labelBox = [label.text boundingRectWithSize: limitLabel
                                                  options: NSStringDrawingUsesLineFragmentOrigin
                                               attributes: @{ NSFontAttributeName:label.font }
                                                  context: context].size;

    size = CGSizeMake(ceil(labelBox.width), ceil(labelBox.height));
    return size.height;
}

所以你可以像这样使用:

CGFloat sizeOfFontTest = 12.0;
    UILabel *testLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 0, 100, 0)];
    [testLabel setFont: [UIFont systemFontOfSize: sizeOfFontTest]];
    [testLabel setText: @"Hello Stackoverflow Large String Example"];

    CGFloat heightTestLabel = [self getLabelHeight: testLabel];

    [testLabel setFrame: CGRectMake(testLabel.frame.origin.x, testLabel.frame.origin.y, testLabel.frame.size.width, heightAddrsLab)];
    [testLabel setNumberOfLines: sizeOfFontTest / heightTestLabel];

答案 12 :(得分:-6)

此代码用于通过按钮功能按顺时针方向移动四个标签:

(void)onclick
{
    CGRect newFrame;
    CGRect newFrame1 = lbl1.frame;
    CGRect newFrame2 = lbl2.frame;
    CGRect newFrame3 = lbl3.frame;
    CGRect newFrame4 = lbl4.frame;
    lbl1.frame=newFrame;
    lbl4.frame=newFrame1;
    lbl3.frame=newFrame4;
    lbl2.frame=newFrame3;
    lbl1.frame=newFrame2;
}