考虑到它是完全正确的,我不会在这里说任何与接受的答案相矛盾的东西。但是,我将更详细地介绍如何实现这一点。如果您不想通读所有这些并且对在工作项目中使用源代码更感兴趣,我已经上传了example project to GitHub。
基本思想是在方法-tableView: heightForRowAtIndexPath: 中有一个条件来确定当前单元格是否应该展开。这将通过在-tableView: didSelectRowAtIndexPath: 中调用表格的开始/结束更新来触发。在此示例中,我将展示如何制作一个允许一次展开一个单元格的表格视图。
您需要做的第一件事是声明对NSIndexPath 对象的引用。你可以随心所欲地这样做,但我建议使用这样的属性声明:
@property (strong, nonatomic) NSIndexPath *expandedIndexPath;
注意:您不需要在 viewDidLoad 或任何其他类似方法中创建此索引路径。索引最初为 nil 的事实仅意味着该表最初不会有扩展行。如果您希望表格从您选择的行开始展开,您可以在 viewDidLoad 方法中添加类似的内容:
NSInteger row = 1;
NSInteger section = 2;
self.expandedIndexPath = [NSIndexPath indexPathForRow:row inSection:section];
下一步是转到 UITableViewDelegate 方法 -tableView: didSelectRowAtIndexPath: 添加逻辑以根据用户选择更改扩展单元格索引。这里的想法是检查刚刚选择的索引路径与存储在expandedIndexPath 变量中的索引路径。如果两者匹配,那么我们知道用户正在尝试取消选择展开的单元格,在这种情况下,我们将变量设置为 nil。否则,我们将expandedIndexPath 变量设置为刚刚选择的索引。这一切都是在调用 beginUpdates/endUpdates 之间完成的,以允许表格视图自动处理过渡动画。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView beginUpdates]; // tell the table you're about to start making changes
// If the index path of the currently expanded cell is the same as the index that
// has just been tapped set the expanded index to nil so that there aren't any
// expanded cells, otherwise, set the expanded index to the index that has just
// been selected.
if ([indexPath compare:self.expandedIndexPath] == NSOrderedSame) {
self.expandedIndexPath = nil;
} else {
self.expandedIndexPath = indexPath;
}
[tableView endUpdates]; // tell the table you're done making your changes
}
那么最后一步是在另一个UITableViewDelegate方法-tableView: heightForRowAtIndexPath:中。在您为表确定需要更新的每个索引路径触发一次beginUpdates 后,将调用此方法。您可以在此处将expandedIndexPath 与当前正在重新评估的索引路径进行比较。
如果两个索引路径相同,那么这就是你希望展开的单元格,否则它的高度应该是正常的。我使用了值 100 和 44,但您可以使用任何适合您需要的值。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Compares the index path for the current cell to the index path stored in the expanded
// index path variable. If the two match, return a height of 100 points, otherwise return
// a height of 44 points.
if ([indexPath compare:self.expandedIndexPath] == NSOrderedSame) {
return 100.0; // Expanded height
}
return 44.0; // Normal height
}