本文转载自:https://www.mgenware.com/blog/?p=509
在上文中。我们讲了单一样式的UITableViewCell
在Autolayout下的动态高度,本文将在上文的基础上,增加两个地方:
1. 多个样式的UITableViewCell
类型。
2. UITableViewCell
样式动态变化变化。
(可以看到下载过程中只能显示7个Cell,但是下载完成后Cell高度发生了变化,可以显示8个项目)
整个执行方式实际上就是沿用上文的描述的方法,即在heightForRowAtIndexPath
中使用一个Cell做测量并返回高度,在cellForRowAtIndexPath
中继续使用Cell重用机制。只不过这里是两个样式的Cell,所以在UITableView
的heightForRowAtIndexPath
方法中,要准本好两个供测量的Cell。当然,Cell内容加载也是两个。具体改用哪种Cell,是根据数据源中的特定数据,在本例中,当然就是是否指示下载完成的属性。
至于数据变化后Cell的刷新,调用UITableView
的reloadRowsAtIndexPaths
方法就OK了。来简单说一下实现过程(具体请参考源代码)。
首先,选中Storyboard中TableView,把Prototype Cells从1改成2。这样就有两个Prototype Cell了:
然后设计好两个Cell的UI:
注意每个Cell都定义好Autolayout,并且上下都连接上Constraint,否则systemLayoutSizeFittingSize
方法不会返回正确的结果,如下图:
最后别忘了为每一个Cell设置自己的Reuse Identifier。
代码上,多数代码和上文的完全类似,这里就不再多贴了。
看几个比较重要的,比如heightForRowAtIndexPath
方法,只创建两个Cell来测量,Cell的内容加载和测量高度返回和上文讲的类似。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Cell均只创建一次
static NormalCell *normalCell = nil;
static CompletedCell *compCell = nil;
MyTask *task = [_tasks objectAtIndex:indexPath.row];
if (task.isCompleted)
{
if (!compCell) //加载一种Cell
compCell = [self getCompletedCell:task];
return [self getCellHeight:compCell];
}
else
{
if (!normalCell) //加载另一种Cell
normalCell = [self getNormalCell:task];
return [self getCellHeight:normalCell];
}
}
还有
cellForRowAtIndexPath
方法,直接调用加载Cell的方法就可以了:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyTask *task = [_tasks objectAtIndex:indexPath.row];
if (task.isCompleted)
{
return [self getCompletedCell:task];
}
else
{
return [self getNormalCell:task];
}
}