【问题标题】:Change the UITableViewCell Height According to Amount of Text根据文本量更改 UITableViewCell 高度
【发布时间】:2012-04-07 07:12:30
【问题描述】:

我需要能够调整 UITableView 中单个单元格的高度,以使其适合其详细标签中的文本量。

我玩过以下游戏,但对我不起作用:

How do I wrap text in a UITableViewCell without a custom cell

尝试的代码:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20;
}

这不起作用,它在单元格上显示整个字符串,但单元格高度根本不受影响。

【问题讨论】:

标签: ios objective-c iphone uitableview


【解决方案1】:

很简单,只需将其添加到您的代码中即可:

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

它会自动计算行高,然后返回一个浮点数... :-)

希望这会有所帮助!

【讨论】:

  • 它实际上是否适用于 heightForRowAtIndexPath?我的测试中没有。另请参阅 UITableView.h:“从 tableView:heightForHeaderInSection: 或 tableView:heightForFooterInSection: 返回此值:如果标题不为零,则导致高度适合从 tableView:titleForHeaderInSection: 或 tableView:titleForFooterInSection: 返回的值。”我认为它只适用于页眉/页脚高度。
  • 它可以工作,但仅适用于基本的“cell.textLabel”或 Apple 的其他产品。与某些自定义单元格一起使用可能会更难......
  • 仅适用于标准单元...不适用于我的自定义单元。
  • 对我来说,它适用于我的自定义单元格,只需添加您想要的约束即可。
  • 只有在函数estimatedHeightForRowAtIndexPath 中提供估计值时才能完美运行。如果你有一个 imageview 并且它设置为 aspect fit,这将无法正常工作
【解决方案2】:

嗨乔希,

使用tableView:heightForRowAtIndexPath:,您可以在运行时给出每行的大小。现在你的问题是如何从你的字符串中获取高度 NSString 类中有函数通过这段代码你的问题,

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSString *str = [dataSourceArray objectAtIndex:indexPath.row];
    CGSize size = [str sizeWithFont:[UIFont fontWithName:@"Helvetica" size:17] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:NSLineBreakByWordWrapping];
    NSLog(@"%f",size.height);
    return size.height + 10;
}

通过下面的行,您可以设置标签的编号。线到最大。所以在 cellForRowAtIndexPath: 方法中设置它。

cell.textLabel.numberOfLines = 0;

如果您使用一些自定义单元格,则使用此管理所有标签的字符串并获取所有高度的总和,然后设置单元格的高度。

编辑: 从 iOS 8 开始,如果您为标签设置了适当的自动布局约束,那么您只需设置以下委托方法即可实现此目的。

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
   //minimum size of your cell, it should be single line of label if you are not clear min. then return UITableViewAutomaticDimension;    
   return UITableViewAutomaticDimension; 
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

就是这样。无需任何计算。欲了解更多信息,请查看tutorial.

【讨论】:

  • dataSourceArray 包含什么?我的文字?
  • @JoshKahane 是的它s your table dataSource array from where you feed your tables 标签。
  • sizeWithFont has been deprecated
  • 似乎对于 iOS 8.x 和 9.x 它有不同的行为,当我为 iOS 8.x 单元格的标签(大小类)添加不同的字体大小时,具有相同的高度,不尊重标签字体大小(在 iPad 上字体更大,但单元格高度仍然相同)
  • 添加 only UITableViewAutomaticDimensionestimatedHeightForRowAtIndexPathheightForRowAtIndexPath 使用自定义样式时对我有用。 :)
【解决方案3】:

在您的CustomCell 中:记得为您的UILabel 添加上下约束

要根据文本调整 UILabel 高度,只需将 UILabel 行更改为 0 (see the answer here)

然后在你的代码中,只设置 2 行

self.tableView.estimatedRowHeight = 80;
self.tableView.rowHeight = UITableViewAutomaticDimension;

这是我的自定义单元格
这是我的UILabel 约束

您将实现的屏幕

=== 建议 ===
如果您的单元格有一些 UILabelsImages(不像我的示例)那么:

  • 您应该将所有UILabelsImages 放在一个GroupView 中(查看)
  • 为此GroupView 添加constraint top and bottom to supper view(就像我图片中的UILabel)
  • 按照我上面的建议调整 UILabel 高度
  • 根据内容调整GroupView的高度(内容全部为UILabelsImages
  • 最后,像上面的代码一样更改estimateRowHeighttableView.rowHeight

希望对你有所帮助

【讨论】:

  • 如果一行有一些 UILabel 和 Images 会发生什么?
  • @Brave 只需将UILabelsImages 放在组视图中(View)。之后,您可以将 groupview 视为一个UILabel。配置约束并修改代码,就像我的指令一样。我相信它会起作用的
  • 标签有不同的长度,图片有不同的大小。在一行中,它按 label1、image1、label2、image2 排序。能用吗?
  • 当然你可以实现它^^。这是我的另一个问题,它不是你的解决方案,但它包含我实现的图像stackoverflow.com/questions/36420899/…
  • 是的!谢谢你。最后是 iOS 的动态自定义单元格高度。
【解决方案4】:

根据您提供的代码,我认为您只是增加了单元格高度,而不是 cell.textLabel 的高度。

理想情况下,您应该设置 cell.textLabel 的框架大小和单元格,以便您查看单元格中的全文。

查看视图在大小方面有什么问题的一种巧妙方法是将其颜色与背景不同(尝试将 cell.textLabel 背景设置为黄色)并查看是否实际设置了高度。

应该是这样的

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];

    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = cell.textLabel.font;
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
    cell.textlabel.frame.size = labelSize; 
    cell.text = cellText;
}

希望这会有所帮助!

更新:这是一个相当古老的答案,并且此答案中的许多行可能已被弃用。

【讨论】:

  • 试过这个,麻烦的是,首先你不能分配单元格标签大小,它会抛出一个错误,其次,标签高度似乎改变得很好,我可以看到所有的文字,但是它是没有变大的单元格。
  • Josh:CGRect 的 size 属性是只读的,并不特定于单元格标签。尝试 CGRect frame = CGRectMake (xValue, yValue, width, computedHeight); cell.textLabel.frame = 框架;
  • 不,单元格高度没有改变......虽然你刚才的建议确实消除了不可分配的错误。
  • 可能是因为您可以在 [tableView reloadData] 进入编辑模式后使用它。它可能会根据新的单元格框架重新计算。此外,在这种情况下 CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);可能会弄乱它,因为您很难将宽度设置为 280.0f
  • UILineBreakModeWordWrap 在 iOS 6.0 中已弃用,请改用 NSLineBreakByWordWrapping
【解决方案5】:

对于 swift 开发人员:

自定义单元格: 首先,您可以计算文本的高度,如下所示:

func calculateHeight(inString:String) -> CGFloat
    {
        let messageString = inString
        let attributes : [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 15.0)]

        let attributedString : NSAttributedString = NSAttributedString(string: messageString, attributes: attributes)

        let rect : CGRect = attributedString.boundingRect(with: CGSize(width: 222.0, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

        let requredSize:CGRect = rect
        return requredSize.height
    }

设置文本标签

宽度

然后调用这个函数:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        heightOfRow = self.calculateHeight(inString: conversations[indexPath.row].description)

        return (heightOfRow + 60.0)
}

对于基本单元

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
           return UITableViewAutomaticDimension
    }

此功能不适用于自定义单元格

希望它会奏效。

【讨论】:

    【解决方案6】:

    tableView:heightForRowAtIndexPath: 中,您可以获取文本并使用sizeWithFont:constrainedToSize: 来获取文本的大小。

    然后只返回高度加上缓冲区的一些额外间距。

    【讨论】:

      【解决方案7】:

      您可以在全局范围内编写一个方法来制作它,以便在整个应用程序中使用它。您需要根据您的要求传递文本、字体和宽度。

      在 Swift 4 中:

      func heightForText(text: String,Font: UIFont,Width: CGFloat) -> CGFloat{
      
          let constrainedSize = CGSize.init(width:Width, height: CGFloat(MAXFLOAT))
      
          let attributesDictionary = NSDictionary.init(object: Font, forKey:NSAttributedStringKey.font as NSCopying)
      
          let mutablestring = NSAttributedString.init(string: text, attributes: attributesDictionary as? [NSAttributedStringKey : Any])
      
          var requiredHeight = mutablestring.boundingRect(with:constrainedSize, options: NSStringDrawingOptions.usesFontLeading.union(NSStringDrawingOptions.usesLineFragmentOrigin), context: nil)
      
          if requiredHeight.size.width > Width {
              requiredHeight = CGRect.init(x: 0, y: 0, width: Width, height: requiredHeight.height)
      
          }
          return requiredHeight.size.height;
      }
      

      【讨论】:

        【解决方案8】:

        我能够使用自动布局来完成这项工作。确保您的标签捕捉到单元格的顶部和底部(我使用的是原型单元格),并且它的行设置为 0。然后在 tableView:heightForRowAtIndexPath:sizeWithFont:constrainedToSize: 中,您可以通过在文字大小:

        NSString *key = self.detailContent.allKeys[indexPath.row];
        NSDictionary *dictionary = self.detailContent[key];
        NSString *cellText = dictionary[kSMDetailTableViewCellTextKey];
        UIFont *cellFont = [UIFont fontWithName:kFontKeyEmondsans size:12.0];
        CGSize constraintSize = CGSizeMake(252.0f, MAXFLOAT);
        CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
        return labelSize.height;// + 10;
        

        【讨论】:

        • tableView:heightForRowAtIndexPath:sizeWithFont:constrainedToSize: 来自什么协议? tableView:heightForRowAtIndexPath:UITableViewDelegate 中,但 sizeWithFont 部分听起来不像来自 Apple UITableView 协议。 NSString 上的 UIKit 类别中的sizeWithFont 在 iOS 7 中已被弃用,如果这就是所指的。
        【解决方案9】:
        NSString *str;
        NSArray* dictArr;
        
        if (_index==0) {
            dictArr = mustangCarDetailDictArr[indexPath.section];
        
        }
        
        NSDictionary* dict = dictArr[indexPath.row];
        
        
        if (indexPath.section ==0)
        {
        
            str = [dict valueForKey:@"FeatureName"];
            if ([[dict valueForKey:@"FeatureDetail"] isKindOfClass:[NSString class]])
            {
        
                str = [dict valueForKey:@"FeatureDetail"];
        
        
        
            }
            else
            {
                if (dictArr.count>indexPath.row+1)
                {
                    NSDictionary* dict2 = dictArr[indexPath.row+1];
                    if ([[dict2 valueForKey:@"FeatureDetail"] isKindOfClass:[NSString class]])
                    {
        
        
                    }
                }
        
            }
        
        
        }
        CGSize size = [str sizeWithFont:[UIFont fontWithName:@"Helvetica" size:17] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:NSLineBreakByWordWrapping];
        NSLog(@"%f",size.height);
        return size.height + 20;
        
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-20
          • 1970-01-01
          • 1970-01-01
          • 2017-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-25
          相关资源
          最近更新 更多