关于SO的十几个问题是相似的,但似乎没有就最佳方式达成共识。此外,我还没有找到任何适合我的解决方案。与我的自定义UITableViewCell不同的是,我有两个标签,其中一个是自己的视图,还有一个文本视图。所有这三个都应该扩展到它们的内容。
我想知道我的约束设置是否错误,但我不确定我会调整什么。
这是我在IB中的单元格。
内容视图为浅红色,顶部的额外视图为白色,内部带有标签。
文字更改后,我保存文字并更新tableView
:
-(void)textViewDidChange:(UITextView *)textView
{
NSLog(@"row: %i", textView.tag);
[self.textStrings setObject:textView.text atIndexedSubscript:textView.tag];
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
对于tableView:heightForRowAtIndexPath:
方法,我使用高速缓存值作为选定行以外的高度。在这种情况下,我正在创建一个新单元格,配置它,并使用systemLayoutSizeFittingSize:
获取高度。这似乎是最常见的solution。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// use cached height if there is one (and it isn't the selected row)
if ([self.selectedRow integerValue] != indexPath.row && indexPath.row < [self.rowHeights count]){
return [[self.rowHeights objectAtIndex:indexPath.row] floatValue];
}
static NSString *CellIdentifier = @"RMTextViewCell";
RMTextViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[self configureCell:cell forIndexPath:indexPath];
[cell layoutIfNeeded];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
height += 1; // add 1 for border
NSNumber *h = @(height);
[self.rowHeights setObject:h atIndexedSubscript:indexPath.row];
return height;
}
textView确实展开了,但当它转到多行时,顶部标签开始被剪裁。在某些版本中,我在文本更改时已经启动了textView剪辑/扩展。似乎autolayout不确定如何正确计算单元格的高度。
有什么想法吗?
这是我的Github project,里面有一些实验。重要文件为ViewControllers/RMTextViewTableViewController
和Cell/RMTextViewCell
。如果你运行它,请查看“带文本的动态单元格。”
答案 0 :(得分:2)
似乎这可能是一个iOS错误,因为我希望UITextView的高度将被包含为UILabels,当它位于单元格的contentView中时,我们使用systemLayoutSizeFittingSize。无论如何,正如user501836所说,你可以手动计算textView的高度。然后,您需要将其添加到为contentView计算的高度。以下是我在tableView中计算单元格高度的示例:heightForRowAtIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
CGSize textViewSize = [[cell textView] sizeThatFits:CGSizeMake([[cell textView] frame].size.width, FLT_MAX)];
height += textViewSize.height;
return height;
}
答案 1 :(得分:1)
我有同样的问题。 UITabel在UITableViewCell计算中是正确的,但是UITableViewCell中的UITextView计算是不正确的。
因此,只能手动计算高度:
CGSize textViewSize = [cell.textView sizeThatFits:CGSizeMake(cell.textView.frame.size.width, FLT_MAX)];
答案 2 :(得分:0)
我一直在寻找适用于iOS7和iOS8的解决方案。基于jobb上面的答案,我添加了一些代码来处理使用UITextView.contextSize与UITextView.frame.size的轮换。
我还发现在xCode 6中,似乎systemLayoutSizeFittingSize是UITextView的textContainerInsets的一部分。所以我发现在将额外高度添加到systemLayoutSizeFittingSize之前将它们设置为零可以更好地设置间距。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Get the cell once and save it in an NSDictionary. Thisupports cases with multiple cells types.
CCTextViewCell *sizingCell = [self.offscreenCells objectForKey:CellIdentifier];
if (!sizingCell) {
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[self.offscreenCells setObject:sizingCell forKey:CellIdentifier];
}
[self populateCellViewWithData:sizingCell atIndexPath:indexPath];
sizingCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(sizingCell.bounds));
[sizingCell setNeedsLayout];
[sizingCell layoutIfNeeded];
// UITextViews don't autosize well with systemLayoutSizeFittingSize.
// We need to add the sum of the heights of the UITextViews without its textContainerInsets to the height.
// We also need to set the textContainerInsets to zero so that systemLayoutSizeFittingSize give the right number.
// So we do this first.
CGFloat additionalUITextViewsHeight = 0;
for (UIView *subVw in sizingCell.contentView.subviews) {
if ([subVw isKindOfClass:[UITextView class]]) {
UITextView *subTextView = (UITextView*) subVw;
subTextView.textContainerInset = UIEdgeInsetsZero;
CGSize textViewSize = [subTextView sizeThatFits:CGSizeMake(subTextView.contentSize.width, FLT_MAX)];
additionalUITextViewsHeight += textViewSize.height;
}
}
CGFloat height = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + additionalUITextViewsHeight;
return height;
}