如何动态调整UITableViewCell的高度

59
我有一个带可编辑UITextView的传统分组UITableView。这些文本视图可以是单行或多行的,当用户输入并且文本开始新的一行时,我希望单元格会随之增加高度。
我的问题是:我是否需要重新加载整个表格来增加单元格的高度?还有其他方法吗? 我已经搜索了很多,以前的答案和教程只谈论如何计算文本高度,如何实现heightForRowAtIndexPath......这些我已经知道的东西。我的担忧是,为了实现我想要的效果,每次用户输入一个新字符,我都必须计算高度并重新加载表格,这不是非常干净或有效率的做法。
谢谢。
4个回答

94
[tableView beginUpdates];
[tableView endUpdates];

15
尝试一下,这段代码会强制UITableView仅重新加载单元格的大小,而不是单元格内容。 - Andrey Zverev
虽然这基本上是可行的,但是如果您使用自动行转换重新加载单元格,则不会产生像增大单元格一样流畅的动画。 - Peter DeWeese
1
太好了,如果您希望在某些行上实现动画效果,可以与reloadRowsAtIndexPaths一起使用。 - Morten Holmgaard
我在 'shouldChangeTextIn' 函数中添加了这段代码,它可以很好的工作。但是对于换行符不起作用,当输入一个字符后会自动增长。 - jpulikkottil

63

你不必总是重新加载整个表格,而是只需要重新加载那一行。

[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];

3
我遇到了一个大问题...我在单元格中有一个文本框,调用reload(任何内容)会导致我的文本框放弃第一响应者状态。你有什么想法? - Daniel T.
1
以编程方式保存您的行的IndexPath,并将becomeFirstResponder设置为您的TextField。 - Sn0wfreeze
最好还是添加beginUpdates和endUpdates,因为这是你需要添加的技术上的要求。 - Daniel Galasko
@Sn0wfreeze 这不是一个好的建议,你可以仅通过textField获取cell的indexPath https://dev59.com/SmHVa4cB1Zd3GeqPkTTo#27938042 - Daniel Galasko
类似的解决方案是为相同的indexPath调用moveRowAtIndexPath:toIndexPath:(详见此处)。 - malex
显示剩余3条评论

27

更具体地说,是的,您需要实现tableView:heightForRowAtIndexPath:来计算新高度,然后按照rickharrison所说调用[tableView reloadRowsAtIndexPaths:withRowAnimation]。 假设您的单元格可以有扩展高度和正常高度,并且您希望在轻触时它们增长。 您可以执行以下操作:

-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*) indexPath 
{
    if ([expandedPaths containsObject:indexPath]) {
        return 80;
    } else {
        return 44;
    }
 }

-(void)tableView:(UITableView*) didSelectRowAtIndexPath:(NSIndexPath*) indexPath
{
    [expandedPaths addObject:indexPath];
    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

4

-reloadRowsAtIndexPaths:withRowAnimation方法在我改变了UITableViewCell的frame之后并没有调整它的高度。只有在我跟着使用-reloadData方法之后,才实现了调整高度的效果。

[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadData];

也许你引用了错误的indexPath,如果你调试应用程序,你会清楚地看到在调用tableView reloadRowsAtIndexPath:之后,方法tableView:heightForRowAtIndexPath确实被调用了。 - Pedro Borges

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接