首页 文章

NSString sizeWithFont:constrainedToSize:计算错误的高度

提问于
浏览
0

我有一个字幕样式UITableViewCell,其高度根据每个字段的文本长度动态变化 . 问题是如果标签有多行,textLabel的高度(CGSize大小)不会增加 .

http://s10.postimg.org/6urher7s9/text_Label.png

奇怪的是,detailTextLabel的高度正在增加(CGSize size2) . 计算两个高度的代码是相同的 .

http://s21.postimg.org/m0af4gyw7/detail.png

这是我的功能:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    SETLISTFMNS0Song *song = [[[selectedSetlist.sets objectAtIndex:indexPath.section] songs]objectAtIndex:indexPath.row];
    CGSize size = [song.name sizeWithFont:[UIFont fontWithName:setlistFont size:labelFontSize] constrainedToSize:CGSizeMake(self.setsTable.bounds.size.width, CGFLOAT_MAX)];
    NSLog(@"Label: \"%@\" \tLabel Size: %f W %f H", song.name, size.width, size.height);

    NSMutableString *detail;
    if ([song cover]) {
        detail = [[NSMutableString alloc] initWithFormat:@"(%@ cover)", [[song cover] name]];
    }
    if ([song with]) {
        if (!detail) {
            detail = [[NSMutableString alloc] initWithFormat:@"(with %@)", [[song with] name]];
        }
        else {
            [detail appendFormat:@" (with %@)", [[song with] name]];
        }
    }
    if ([song info]) {
        if (!detail) {
            detail = [[NSMutableString alloc] initWithFormat:@"(%@)", [song info]];
        }
        else {
            [detail appendFormat:@" (%@)", [song info]];
        }
    }

    if (detail.length != 0) {
        CGSize size2 = [detail sizeWithFont:[UIFont fontWithName:setlistFont size:detailFontSize] constrainedToSize:CGSizeMake(self.setsTable.bounds.size.width, CGFLOAT_MAX)];
        size.height += size2.height;
        NSLog(@"Detail Label: \"%@\" \tDetail Label Size: %f W %f H", detail, size2.width, size2.height);
    }

    return size.height + 5;
}

我还在cellForRowAtIndexPath中将textLabel的numberOfLines属性设置为0以支持多行:

cell.textLabel.numberOfLines = 0;
cell.detailTextLabel.numberOfLines = 0;

UPDATE: 感谢@josh我现在明白为什么会这样 . 我将宽度约束设置为UITableView的宽度,这太宽了 . 任何人都知道如何在创建之前找到UILabel的宽度?哈!

谢谢!

2 回答

  • 1

    函数的多长时间约束单元格的整个宽度,但您的标签可能不是单元格的整个宽度 .

    我怀疑发生的事情是 song.info 只是足够短,如果线条是单元格的整个宽度,它将适合一行,并且你的歌曲 detail 足够长,它正在计算正确的行数,但不是这样只要超过计算的高度 .

    所有这些,我想你需要做的是找出 textLabeldetailTextLabel 的宽度,并将约束设置为这些值 .

    Update - A way of calculating label widths

    由于单元格内部标签的宽度取决于单元格的宽度,并且因为在 heightForRowAtIndexPath: 时调用了单元格's aren',我们需要想出一种方法来了解标签' widths before they the widths are set. The only way to do this is to set the widths ourselves. Here' s我将如何操作它:

    MyCell.h

    #import <UIKit/UIKit.h>
    
    @interface MyCell : UITableViewCell
    
    + (CGFloat)textLabelWidthForCellOfWidth:(CGFloat)cellWidth;
    
    @end
    

    MyCell.m

    #import "MyCell.h"
    
    @implementation MyCell
    
    - (void)layoutSubviews {
        [super layoutSubviews];
    
        CGRect frame = self.textLabel.frame;
        frame.size.width = [MyCell textLabelWidthForCellOfWidth:self.frame.size.width];
        self.textLabel.frame = frame;
    }
    
    + (CGFloat)textLabelWidthForCellOfWidth:(CGFloat)cellWidth {
        // This calculation can be as complex as necessary to account for all elements that affect the label
        return cellWidth - 20;
    }
    
    @end
    

    然后在 heightForRowAtIndexPath: 实现中,您可以调用相同的类方法:

    CGFloat labelWidth = [MyCell textLabelWidthForCellOfWidth:self.tableView.frame.size.width]; // Since non-grouped cells are the full width of the tableView
    CGSize size2 = [detail sizeWithFont:[UIFont fontWithName:setlistFont size:detailFontSize] constrainedToSize:CGSizeMake(labelWidth, CGFLOAT_MAX)];
    

    您将为需要引用的每个标签创建单独的Class Method() .

  • 0

    看着你的代码我发现你缺少定义“lineBreakMode” .

    CGSize theSize = [song.name sizeWithFont:[UIFont fontWithName:setlistFont size:labelFontSize] constrainedToSize:CGSizeMake(self.setsTable.bounds.size.width, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
    

    用这个更新你的代码 . 我希望它能解决你的问题 . 祝好运

相关问题