如何计算自定义展开/折叠UITableViewCell的高度动态
我有一个有趣的场景。我有一些在单独的xib文件中设计的自定义UITableViewCells。其中之一有一个UIImageView,它将加载大小不恒定的图像,所以这意味着UIImageView的高度必须灵活。这个单元格还有一个包含UILabels的UIView,并且UIView的大小是不变的,比如100。我想展开并折叠didselectrowatindexpath
事件上的单元格。要折叠单元格,我必须隐藏有一些标签的UIView。请在这方面指导我达到目标。 另外我的问题是“如何计算细胞展开和折叠时行的高度。”谢谢如何计算自定义展开/折叠UITableViewCell的高度动态
编辑:这是我所尝试过的。 。 。但失败
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
static DynamicTableViewCell *cell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
});
[self setUpCell:cell atIndexPath:indexPath];
CGFloat cellHeight = [self calculateHeightForConfiguredSizingCell:cell];
if(cellHeight >0) {
if(cell.isExpanded) {
return cellHeight;
}
else
{
return (cellHeight - detailViewHeight); // cell.detailView.frame.size.height = 100
}
}
else {
return cellHeight;
}
}
首先你不应该有,因为性能原因,任何参考实例,以你的。
其次,您应该使用模型以正确的方式构建您的单元格。所提供的代码根本不显示模型存储的使用情况。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Say you have a array of models NSArray<YourModel *> *dataSource;
YourModel *model = dataSource[indexPath.row]; // hope you have only one section.
}
三是使用像MVVM或VIPER,或任何MVC架构的好方法,因为如果你没有一个你可能会在你的产品的未来支持问题。所以在MVVM的情况下YourModel就像ViewModel。
要定义动态高度单元格的状态,请使用属性isExpanded
。这是一个好点,但它应该在另一个地方定义 - YourModel
。如果你能以正确的方式做到这一点,那么实际上你就会知道没有细胞的细胞状态。
@interface YourModel ...
@property BOOL isExpanded;
@end
要确保你正确地改变你的状态didSelect:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
YourModel *model = dataSource[indexPath.row];
model.isExpanded = !model.isExpanded; // inverse works like switch
// Then relayout your row
[tableView beginUpdates];
// I commented next line because it might not be needed for you
// Test it please
// [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
}
所以回到heightForRow:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Say you have a array of models NSArray<YourModel *> *dataSource;
YourModel *model = dataSource[indexPath.row]; // hope you have only one section.
// It's better to extract next code to function or any class, but not in your YourModel.
CGSize imageSize = [model.image doSizeCalulation]; // Use your algorithm to calculate image size
CGSize shortText = [model.shortText sizeWithAttributes:@[/* font attributes */]];
// If the cell is expanded then we should calculate height of text else height is zero.
CGSize fullText = model.isExpanded ? [model.fullText sizeWithAttributes:@[/* font attributes */]]; : 0;
// just sum
return imageSize.height + shortText.height + fullText.height;
}
另一种方式来实现这一目标用UITableViewAutomaticDimension
(只返回它heightForRow方法)。在这种情况下,您应该正确设置约束,并在运行时根据isExpanded属性更改fullText的高度约束常量。
嗨亚历山大Shitikov,我谢谢你从我的内心深处这样一个详细的答案。我是iOS新手,你的这种详细回复真的帮助我。还有一些小问题需要回答,我想改变单元格的高度,以便在didselectrowatindexdexpath上做出折叠/展开效果。请在这方面指导我。 –
我也无法理解,只有我的单元格引用了imageView和IBOutlets的标签。那么如何实现CGSize imageSize = [model.image doSizeCalulation];接下来,您还说明了isExpanded属性应该在模型中,我的问题是“那么我将如何在didselectrowatindexdex函数中更新它,请您提供一些示例代码。我会很感激。 –
你好!请再看看答案,有一个代码块与didSelectRow的例子,它清楚地说明你应该如何更新isExpanded属性 –
向我们展示一些代码。你试过什么了? – onnoweb