Xcode 6:Table 单元格中的标签不会展开/展开后显示更长的文本/与单元格对齐

Xcode 6: Label in Table Cell won't expand / display longer text upon expansion / line up with cell

问题:

我在 table 单元格中有一个标签,如下所示:

编辑: 虽然 table 视图不使用 AutoLayout,但单元格的 xib 会。这是它的样子:

现在,“...”表示评论(文本)太长,无法显示。然后用户可以单击单元格,这会向下展开单元格和标签,然后会显示其余文本。

这是 heightForRowAtIndexPath 的代码:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    if (tableView == self.rateAndReviewView.ratingsTable) {
        BOOL isSelected = [self.selectedIndexPaths containsObject:indexPath];

        CGFloat maxHeight = MAXFLOAT;
        CGFloat minHeight = 40.0f;

        if (isSelected){
            CGFloat constrainHeight = isSelected?maxHeight:minHeight;
            CGFloat constrainWidth  = tableView.frame.size.width - 20.0f;
            //
            SQLReview *review = [reviewsArray objectAtIndex:indexPath.row];
            NSString *text       = review.comment;
            CGSize constrainSize = CGSizeMake(constrainWidth, constrainHeight);

            CGSize labelSize = [text sizeWithFont:[UIFont systemFontOfSize:15.0f]
                                  constrainedToSize:constrainSize
                                  lineBreakMode:NSLineBreakByWordWrapping];

            CGFloat labelHeight = labelSize.height;

            return MAX(labelHeight+20, 100.0f);
        } else {
            minHeight = 100.0f;
            return  minHeight;
        }
    }
}

这是 cellForRowAtIndexPath 的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (tableView == self.rateAndReviewView.ratingsTable) {
        static NSString *CellIdentifier = @"Cell";

        VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if(cell==nil){
            cell = [[[NSBundle mainBundle] loadNibNamed:@"ReviewCell" owner:nil options:nil] objectAtIndex:0];
        }

        [cell.contentView.layer setBorderWidth:0.5f];
        cell.contentView.backgroundColor = [UIColor whiteColor];

        SQLReview *review = [reviewsArray objectAtIndex:indexPath.row];
        cell.usernameLabel.text = (review.user_name == nil) ? @"" : review.user_name;
        cell.datetimeLabel.text = (review.datetime == nil) ? @"" : [review.datetime substringToIndex:10];
        cell.commentLabel.text = (review.comment == nil) ? @"" : review.comment;
        cell.commentLabel2.text = (review.comment == nil) ? @"" : review.comment;

        float overallScore = (review.overall == nil) ? 0.0f : [review.overall floatValue];

        NSArray *overallImageViewArray = @[cell.overallStarImageView1, cell.overallStarImageView2, cell.overallStarImageView3, cell.overallStarImageView4, cell.overallStarImageView5];

        if([selectedIndexPaths containsObject:indexPath]) {
            cell.commentLabel.hidden = YES;
            cell.commentLabel2.hidden = NO;

            CGSize commentLabelComputeSize = [cell.commentLabel2.text sizeWithFont:cell.commentLabel2.font constrainedToSize:CGSizeMake(cell.commentLabel2.frame.size.width, CGFLOAT_MAX) lineBreakMode:cell.commentLabel2.lineBreakMode];

            CGFloat commentLabelHeightOffset = (commentLabelComputeSize.height - cell.commentLabel2.frame.size.height > 0) ? (commentLabelComputeSize.height - cell.commentLabel2.frame.size.height) : 0;

            cell.commentLabel2.frame = CGRectMake(cell.commentLabel2.frame.origin.x, cell.commentLabel2.frame.origin.y, cell.commentLabel2.frame.size.width, cell.commentLabel2.frame.size.height + commentLabelHeightOffset);

            cell.commentLabel2.autoresizingMask = UIViewAutoresizingFlexibleHeight;
            cell.commentLabel2.numberOfLines = 0;

        } else {
            cell.commentLabel.hidden = NO;
            cell.commentLabel2.hidden = YES;
        }

        [CommonUtilities displayStarRatingsWithScore:overallScore starImageViewArray:overallImageViewArray];

        return cell;
    }
    return nil;
}

heightForRowAtIndexPath 中的 isSelected 部分确实有效,并且 table 单元格确实在点击时明显展开,但文本保持不变 - 至少,在 iOS 7 台以上设备。

编辑: 我还注销了 cell.commentLabel2.frame 的值,方法是添加:

NSLog(@"VenueTabViewController: cellForRow: contains indexpath %@, size: %@", indexPath, NSStringFromCGRect(cell.commentLabel2.frame));

cellForRowAtIndexPathifelse中,显示如下:

第一次点击:
VenueTabViewController:cellForRow:包含索引路径 {length = 2,path = 0 - 1},大小:{{20, 31}, {285, 60.579999999999998}}

第二次点击:
VenueTabViewController:cellForRow:包含索引路径 {length = 2,path = 0 - 2},大小:{{20, 31}, {285, 21}}

所以它的大小确实发生了变化。

我试过的:

我用谷歌搜索了一下,发现 [string sizeWithFont:[UIFont systemFontOfSize:15.0f] constrainedToSize:constrainSize lineBreakMode:NSLineBreakByWordWrapping]; 已经贬值了。因此,我将上面与之相关的行替换为:

CGSize labelSize = [text sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}]; 
CGFloat labelHeight = ceilf(labelSize.height);

这不仅没用,还阻止了细胞的扩张,我认为这可能是一种倒退。

我也尝试添加以下内容,因为为什么不:

VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if(cell==nil){
    cell = [[[NSBundle mainBundle] loadNibNamed:@"ReviewCell" owner:nil options:nil] objectAtIndex:0];
}

[cell.commentLabel sizeToFit];

但还是不行。

然后,我简单地将 commentLabelHeightOffset 替换为 100,只是为了测试是否会发生任何变化:

cell.commentLabel2.frame = CGRectMake(cell.commentLabel2.frame.origin.x, cell.commentLabel2.frame.origin.y, cell.commentLabel2.frame.size.width, cell.commentLabel2.frame.size.height + commentLabelHeightOffset);

什么都没发生。

编辑: 这是我所做的,最终获得了关注——我按照 saif 的建议删除了单元格上的 AutoLayout。现在,虽然细胞确实在扩张,标签也随之扩张,但出于某种原因,我得到了这个:

我检查了代码,标签框架的 X 和 Y 没有改变(只是框架高度)并且文本在实际文本之前没有 "new lines"。

请问有什么帮助吗?

尝试自动调整大小:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  cell.commentLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight;
  cell.commentLabel.numberOfLines = 0;

  return cell;
}

如果您使用的是手动布局,那么您必须将标签的 numberOfLines 属性 设置为 0,并且您还需要在设置标签后调用 -sizeToFit文本。 在这之后您可能还需要相应地更改其他一些框架,这样标签就不会重叠任何东西。

如果您使用的是 AutoLayout,那么仍然需要设置 numberOfLines,但这取决于您的约束,如果您将标签的左右设置为超级视图的左右,那么它可以推断出最大宽度并垂直增加标签。

无论如何,您的屏幕截图清楚地显示标签设置为 numberOfLines = 1,您的单元格高度看起来没问题,这是预料之中的,因为您是在代码中用设置的宽度计算它的。这是未被触发的标签的呈现。首先将 numberOfLines 更改为 0,然后在 layoutSubviews 中(如果您手动执行操作),您需要 sizeToFit

试试这个,将框架设置为行单元格中的 desc 标签(取决于文本大小),并在要展开单元格时重新加载 table 视图。

cellForRowAtIndexPath

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    //code to add desc label
}

CGSize suggestedSize = [descriptionText sizeWithFont:descLabel.font constrainedToSize:CGSizeMake(descLabel.frame.size.width, FLT_MAX) lineBreakMode:descLabel.lineBreakMode];
float padding = 20;
[descLabel setFrame:CGRectMake(padding, CGRectGetMaxY(nameLabel.frame), CGRectGetWidth(tableView.frame)-(2*padding), suggestedSize.height)];

如果您在自定义单元格中使用自动布局,那么

  1. 保留备份,并取消选中自动布局
  2. select iPhone 在下拉列表中 select 禁用尺寸 class

如果行高有问题,

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    

    CGSize suggestedSize = [descriptionText sizeWithFont:descLabel.font constrainedToSize:CGSizeMake(descLabel.frame.size.width, FLT_MAX) lineBreakMode:descLabel.lineBreakMode];
    float heightOfRow = CGRectGetMaxY(nameLabel.frame)+suggestedSize.height+5; // height of name label(as it is single line supported) + height of desc label + bottom padding
    return heightOfRow;
}

希望对您有所帮助

如果您想继续使用自动版式:

-将 numberOfLines 设置为“0”

-实现以下两个TableView方法

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

Working with Self-Sizing Table View Cells这里有一个有用的参考。