如何调整UITableViewCell的大小以适应其内容?

我有一个UITableview与多个可重用的TableViewCells。 在一个单元格中,我有一个UITextView ,它调整自己以适应其内容。 现在我只需要调整TableViewCell的contentView ,这样我就可以阅读while文本了。 我已经尝试过了:

 cell2.contentView.bounds.size.height = cell2.discriptionTextView.bounds.size.height; 

要么:

 cell2.contentView.frame = CGRectMake(0, cell2.discriptionTextView.bounds.origin.y, cell2.discriptionTextView.bounds.size.width, cell2.discriptionTextView.bounds.size.height); 

在该方法中:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {} 

但它不会工作。

有谁知道如何做到这一点?

新代码:

  @implementation AppDetail CGFloat height; … - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {… cell2.TextView.text = self.text; [cell2.TextView sizeToFit]; height = CGRectGetHeight(cell2.TextView.bounds); … } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) { return 143; } if (indexPath.row == 1) { return height; } return 0; } 

你需要你实现heightForRowAtIndexPath

假设要在textView中显示的数据存储在一个NSArray中。

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat cellheight = 30; //assuming that your TextView's origin.y is 30 and TextView is the last UI element in your cell NSString *text = (NSString *)[textArray objectAtIndex:indexpath.row]; UIFont *font = [UIFont systemFontOfSize:14];// The font should be the same as that of your textView CGSize constraintSize = CGSizeMake(maxWidth, CGFLOAT_MAX);// maxWidth = max width for the textView CGSize size = [text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap]; cellHeight += size.height; //you can also add a cell padding if you want some space below textView } 

您只能在tableView:heightForRowAtIndexPath: delegate方法中调整UITableViewCell的大小。

你必须估计当tableView被加载时,每一行调用该方法时文本的大小。

这是我为解决问题所做的。

 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSString * yourText = self.myArrayWithTextInIt[indexPath.row]; // or however you are getting the text return additionalSpaceNeeded + [self heightForText:yourText]; } -(CGFloat)heightForText:(NSString *)text { NSInteger MAX_HEIGHT = 2000; UITextView * textView = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, WIDTH_OF_TEXTVIEW, MAX_HEIGHT)]; textView.text = text; textView.font = // your font [textView sizeToFit]; return textView.frame.size.height; } 

编辑

虽然我使用了这个解决scheme一段时间,但是我发现了一个更优化的解决scheme,我build议使用它,因为它不需要分配整个textView来工作,并且可以处理大于2000的文本。

 -(CGFloat)heightForTextViewRectWithWidth:(CGFloat)width andText:(NSString *)text { UIFont * font = [UIFont systemFontOfSize:12.0f]; // this returns us the size of the text for a rect but assumes 0, 0 origin CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}]; // so we calculate the area CGFloat area = size.height * size.width; CGFloat buffer = whateverExtraBufferYouNeed.0f; // and then return the new height which is the area divided by the width // Basically area = h * w // area / width = h // for w we use the width of the actual text view return floor(area/width) + buffer; } 

这是iOS 7+的更新版本,更干净(没有额外的方法)

 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { UIFont * font = [UIFont systemFontOfSize:15.0f]; NSString *text = [getYourTextArray objectAtIndex:indexPath.row]; CGFloat height = [text boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width, maxHeight) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName: font} context:nil].size.height; return height + additionalHeightBuffer; } 

正如@Rob Norback所说,有一种叫做UITableViewAutomaticDimension东西。

对于Swift来说,从UITableViewCell实时调整内容大小的最简单的方法就是添加这个。

 override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } 

这个线程已经有一段时间了,但在iOS 8中引入了UITableViewAutomaticDimension 。 你必须从单元格的顶部到底部设置约束,就像滚动视图一样,以使其工作。 但在此之后,只需将以下代码添加到viewDidLoad()

 tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 122.0 

确保你的估计高度尽可能接近真实的东西,否则你会得到一些越野车滚动。

我赞成Jure的这个解决scheme

  • 首先,将textview的约束设置为其超级视图(本例中为单元格的contentView)。
  • 禁用textView.scrollEnabled
  •  table.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = 44; 

    如果最后,你的代码不起作用,那就用这个代替

     - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44; } 
  • 像这样实现UITextViewDelegate

     - (void)textViewDidChange:(UITextView *)textView { CGPoint currentOffset = self.tableView.contentOffset; [UIView setAnimationsEnabled:NO]; [self.tableView beginUpdates]; [self.tableView endUpdates]; [UIView setAnimationsEnabled:YES]; [self.tableView setContentOffset:currentOffset animated:NO]; } 

使用UITableViewAutomaticDimension将这两个方法添加到ViewController应该会有效。 它在我的UITextView中embedded一个可变长度的文本的UITableViewCell时,已经为我工作。

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

在UITableViewCell的UILabel子视图中,我通过设置标签的约束(使用storyboard,Xcode 8.3.2)来完成标签的自动resize。

这是工作,因为显然标签和单元格的默认行为是sizeToFit。 同样也应该为UITextView工作。