iOS - 在旋转时使用动态单元格高度重绘 TableViewCells

Posted

技术标签:

【中文标题】iOS - 在旋转时使用动态单元格高度重绘 TableViewCells【英文标题】:iOS - Redraw TableViewCells with Dynamic Cell heights on rotation 【发布时间】:2014-07-07 22:15:06 【问题描述】:

如何在设备旋转后重新绘制单元格?

当我在 iPhone 上进行测试时,默认方向是纵向,因此当设备处于纵向时,我的动态单元格与它们需要的高度一样高:这意味着当我旋转到横向时,会有很多空白单元格中的空间。当我在 iPad 上测试时,情况正好相反。旋转到纵向时,我的部分文本被截断,因为默认值为横向。我有两个设备的单独故事板,两个视图控制器都设置为“方向:推断”

(纵向) (横向)

这就是 iPhone 上发生的情况 - 拉伸标签具有深红色背景,因此您可以看到标签的实际大小。但是,单元格高度不会重新计算,并且由于底部标签被限制在单元格的底部,因此它们一直位于底部。如果我从拉伸标签(带有背景的标签)添加一个约束到单元格的底部,它所做的就是像这样拉伸标签:

(标签被拉伸)

这告诉我的是,现在我无法让单元格知道方向是什么,并在它更改为适合时重新绘制。这是我的heightForRowAtIndexPath 代码,用于计算单元格的高度:

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

    if (!self.opCell)
        
            self.opCell = [self.container dequeueReusableCellWithIdentifier:@"OPCell"];
        
    self.opCell.opName.text = [[self.data objectAtIndex:indexPath.row] valueForKey:@"name"];
    [self.opCell layoutIfNeeded];
    CGFloat height = [self.opCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    return height + 1;

到目前为止,为了让它旋转,我尝试了[self.container reloadData],其中容器是我的TableViewwillRotateToInterfaceOrientationdidRotateToInterfaceOrientation 无济于事。我还尝试将它放在 viewDidLoad 中,以便在以正确高度以横向模式加载视图时检测和加载,但这也不起作用。对于 iPhone,无论我做什么,它都会加载纵向视图的高度并且不会在旋转时更新。

我发现了一些我认为可能会有所帮助的问题,但我似乎无法让 this answer 为我工作,尽管这似乎与我的问题相同,而 this one 似乎更专注于单元格宽度大于高度,我不确定它是否以相同的方式适用。

Here 甚至是一个教程,当我在 iPhone 上运行它时,它也没有在旋转时调整 TableViewCells 的大小。

This tutorial 似乎对更改桌子高度有所了解,因此我将begin/endUpdates 代码添加到我的didRotateToInterfaceOrientation 中,认为这可能会导致更改,但这并没有奏效。

所以,如果有人有任何建议或知道解决方案,将不胜感激,因为我正在用这个碰壁!

【问题讨论】:

你应该把与计算高度无关的东西移出方法......这是一个好的开始。 我需要 heightForRowAtIndexPath 方法中的所有代码。我必须声明单元格,声明我想要动态高度的标题,然后告诉它用最后两行计算高度。动态单元格比它们需要的更复杂,这很有效。 这是一个很好的教程如何创建一个动态的 tableViewCells。 raywenderlich.com/73602/… @samir 谢谢!我采用了一种更简单的方法,因为我认为该站点上的动态单元格教程更适用于 ios6 或更早版本。那里的示例代码似乎正在做我需要的事情 - 考虑将其作为答案添加一些细节/赏金的关键点...... 【参考方案1】:

看来你在这里做了一个自动换行。因此,根据我之前的经验,我建议您: 1) 使用 sizeWithFont 或具有适当换行模式的较新 iOS7 版本。 2)您可以为您的“opCell”实现layoutSubview,您可以在其中重新定义帧大小。 3) 计算旋转过程中的单元格高度。确保根据新的 tabelView Bounds 正确设置宽度。 4) 您还可以实现estimatedHeightForRowAtIndexPath 以快速估计表重新加载操作的大小。

希望对你有帮助!!

【讨论】:

1) 我目前正在调整标签大小,只是在情节提要中使用 0 行数,它似乎正在工作。我应该在 heightForRowAtIndexPath 中使用 sizeWithFont 吗?这只会影响标签高度吗?对于 2 和 3,如果我在那里而不是 heightForRowAtIndexPath,如何在这些方法中实现单元格大小?【参考方案2】:

所以我发现了我的问题。关注this tutorial,我发现我失踪了。

我不得不:

    子类化我正在拉伸的标签并声明 preferredMaxLayout 满足屏幕宽度

    在我的heightForRowAtIndexPath 中,我需要告诉单元格获取并更新屏幕的当前宽度

有关详细信息,请参阅教程。希望这个问题和答案对将来的人有所帮助,因为这非常麻烦。

【讨论】:

【参考方案3】:

您可以使用与here 相同的技巧。那就是呼唤:

[tableView beginUpdates];
[tableView endUpdates];

中间没有任何东西。这将触发表格视图的高度重新计算。

【讨论】:

正如我所说,我已经尝试过了,但没有得到任何结果。我试过把这个方法放在ViewDidLoadviewDidLayoutSubviewsheightForRowAtIndexPathdidRotateFromInterfaceOrientationreloadRowsAtIndexPath中。还有什么地方可以放吗? 我只会设置在didRotateFromInterfaceOrientation。您提到的大多数其他方法都是由begin/endUpdates 触发的,可能会导致循环。 我已经单独在那里以及在其他一些地方尝试过,但这对我不起作用。

以上是关于iOS - 在旋转时使用动态单元格高度重绘 TableViewCells的主要内容,如果未能解决你的问题,请参考以下文章

旋转时表格单元内标签的动态高度

iOS8“现在”改变动态单元格的高度,重新内部单元格内容

第一个单元格上的 iOS 8 自动表格视图高度错误

具有动态高度单元格但所有单元格同时显示的 iOS 表格视图

在tableview ios中使用UILabel的单元格的动态高度

使用Objective C增加单元格数量时如何动态增加UITableView高度?