自动调整UILabel的高度

时间:2013-03-07 12:42:02

标签: ios objective-c nsstring uilabel objective-c-category

我正在使用以下两种方法(一种是NSString的类别,另一种是UILabel的类别)来根据其中的文本自动调整标签的高度。它适用于大部分,但它有一些不可预测的结果。我不太确定问题可能发生在哪里,我希望你们中的一些人可以提供帮助。首先,这是有问题的方法:

NSString类别:

- (CGFloat) fontSizeWithFont: (UIFont *) font constrainedToSize: (CGSize) size minimumFontSize: (CGFloat) minimumFontSize
{
    CGFloat fontSize = [font pointSize];
    CGFloat height = [self sizeWithFont: font constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
    UIFont *newFont = font;

    // Reduce font size while too large, break if no height (empty string)
    while (height > size.height && height != 0 && fontSize > minimumFontSize) {
        fontSize--;
        newFont = [UIFont fontWithName: font.fontName size: fontSize];
        height = [self sizeWithFont: newFont constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
    };

    // Loop through words in string and resize to fit
    for (NSString *word in [self componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]) {
        CGFloat width = [word sizeWithFont: newFont].width;
        while (width > size.width && width != 0 && fontSize > minimumFontSize) {
            fontSize--;
            newFont = [UIFont fontWithName: font.fontName size: fontSize];
            width = [word sizeWithFont: newFont].width;
        }
    }
    return fontSize;
}

UILabel类别:

- (void) sizeToFitMultipleLines
{
    if (self.adjustsFontSizeToFitWidth) {
        CGFloat adjustedFontSize = [self.text fontSizeWithFont: self.font constrainedToSize: self.frame.size minimumFontSize: self.minimumScaleFactor];
        self.font = [self.font fontWithSize: adjustedFontSize];
    }
    [self sizeToFit];
}

正在发生的问题是标签的高度在其顶部和底部有空的空间,并且其中的字符串越长,空的空间越大。单行标签在标签的框架内可能在其上方和下方有10个像素,但是六行字符串可能有近100个像素。我无法在上述方法中追踪这个额外空间的来源。

其次,标签的宽度有时会调整,我只想改变高度。我猜测[self sizeToFit]是造成这个特殊问题的原因,但我不完全确定,因为如果移除它,高度仍未调整。 编辑:我已经通过在标签大小适合后手动重新定位标签来修复此宽度问题(其X坐标现在是屏幕宽度减去标签宽度除以2)。

有什么想法?如果您需要其他信息或代码,请询问。在调用相关标签上的[sizeToFitMultipleLines]方法之前,我总是设置字体,所以这不是问题。

1 个答案:

答案 0 :(得分:6)

我试过这个,它为我工作。希望这可以帮助你一点。

-(void) getDynamicHeightWithString:(NSString*)labelText forWidth:(CGFloat)lblWidth forPoint:(CGPoint)point
{
    //Create Label
    UILabel *label = [[UILabel alloc] init];
    label.text = labelText;
    label.numberOfLines = 0;
    label.lineBreakMode = NSLineBreakByWordWrapping;

    //Set frame according to string
    CGSize size = [label.text sizeWithFont:label.font
                         constrainedToSize:CGSizeMake(lblWidth, MAXFLOAT)
                             lineBreakMode:UILineBreakModeWordWrap];
    [label setFrame:CGRectMake(point.x , point.y , size.width , size.height)];

    //Add Label in current view
    [self.view addSubview:label];    

}

使用

NSString *labelText = @"We are what our thoughts have made us; so take care about what you think. Words are secondary. Thoughts live; they travel far.The issue that's occurring is that the height of the label has empty space at its top and bottom, and that the longer the string inside it is, the larger that empty space is. A single line label might have perhaps 10 pixels above and below it inside the label's frame, but a six-line string may have almost 100 pixels. I'm not able to track down where this extra space is coming from in the methods above.";

[self getDynamicHeightWithString:labelText forWidth:200 forPoint:CGPointMake(15, 15)];