在UITableView中显示和隐藏特定的单元格types(可能带有animation)

我有一个UITableView并已经看到了这种效果,并希望为我们的后续数据实现它:

menu_header menu_subheader * item * item menu_subheader * item * item * item 

基本上,我只想显示标题和子标题,然后当用户点击其中一个子标题时,它显示这些项目(最好在一个animation块中)并适当地调整其他单元格。 喜欢这个:

在这里输入图像说明

是否有预构build的组件可以做到这一点? 想想看,似乎我想设置这些项目单元格隐藏。 我已经看到这个https://github.com/peterpaulis/StaticDataTableViewController,但它看起来不适用于dynamic数据。 看来这应该是非常简单的。 关于如何完成这个任何想法? 理想情况下,我希望它能够当你点击它插入数据,然后如果你点击另一个子标题,closures另一个,并添加到该子标题。

要在表格视图中实现“折叠”,您有两个select:

  • 根据每节的折叠/展开属性控制节中单元格的数量。 在折叠或展开时,使用tableView上的insertdeleteRowsAtIndexPaths:withRowAnimation:方法。
  • 使用委托方法控制单元格的高度 。 根据每节的折叠/展开属性将折叠节返回零。 在折叠或展开时,调用beginUpdates紧跟着endUpdates重新计算高度,并为新布局设置animation。

我在这个GitHub仓库中创build了第二个选项的简单实现。 如果您还有其他问题,请告诉我。

你必须删除并插入单元格到你的表格视图,而不是黑客的高度。

我们使用一个控制器的表视图,让您“隐藏/显示”单元格,而实际上处理表视图中行的删除/重新插入。

“切换细节”在Demo上的工作方式与您所要实现的非常相似:

 - (IBAction)toggleDetails:(id)sender { // Hide if all hiddeable rows are hidden, show all otherwise [self.topSection setObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, 3)] hidden:(![self.topSection isObjectAtIndexHidden:1] && ![self.topSection isObjectAtIndexHidden:2] && ![self.topSection isObjectAtIndexHidden:3])]; } 

更改单元格的高度以“隐藏”它们并不是最佳select,因为委托单元会多次询问其大小,单元格将被实例化并configuration为不可见。


示例库将行数据保留在内存(每行一个对象),同时重用单元。 对于大多数项目来说,这应该是可以的,但也许在你的情况下,不仅所有的对象都不应该在内存中,而且你也不应该一次抓取所有的对象。

使你的头部将Tableview部分和子头部将行…而在didSelectRow委托方法插入行,这将是你的项目。

有一个来自Apple的示例代码 ,可以帮助您获得此结果。
主要区别在于苹果示例代码是触发动作并显示相关子视图的标题,但这不是阻塞问题。
你可以使用普通的单元格来实现,通过插入和删除行select其中之一。
重要的是,您需要重新映射数据源信息或将信息与另一个集合配对,以获取该单元格的状态:打开或closures以及子标题或项目以标识它们,并在select它时select正确的操作。
同样重要的是保持数据模型(数据源)和单元格数量之间的一致性,如果您使用批量操作来插入和删除单元格不会是一个问题。 如果你不这样做,你会看到很多例外。
看看这里也是

我其实只是想添加评论,但声誉问题…

无论如何,我个人最喜欢的扩展/折叠UITableView部分的方式在这篇文章中描述: https : //stackoverflow.com/a/1941766/2440562

如果我正确理解问题, menu_headersmenu_subheaders将始终可见,只有项目将被显示/隐藏。

所以这里是我的想法(让我们看看是否可以解释得足够好):你可能有一个想法,每个menu_header有多less个menu_header (静态数或一个数组的元素个数),所以你可以添加一个每个menu_header(实际上只包含一行或一个标题)以及在这两者之间可以添加可扩展的部分( menu_subheaders ),可以像上面提到的答案中所示的那样进行pipe理。 而且,如果您想在先前展开的menu_subheader上折叠另一个,则可以重置它的布尔值,然后使用reloadSections方法重新加载。 你将不得不做一些计算menu_headersmenu_subheaders的位置,但基本上你不必处理单元格高度和行插入和删除(实际上是我最喜欢的部分)。

这里是我提到的计算的快速代码片段(未经testing,完全即兴):

 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return <number_of_menu_headers> + <number_of_menu_subheaders>; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 0) { // handle first menu_header } else if (indexPath.section < 1 + <number_of_menu_subheaders1>) { if (indexPath.row == 0) { // handle the menu_subheader header row } else { // handle the rest of the items } } else if (indexPath.section == 1 + <number_of_menu_subheaders1>) { // handle second menu_header } else if (indexPath.section < 2 + <number_of_menu_subheaders1> + <number_of_menu_subheaders2>) { if (indexPath.row == 0) { // handle the menu_subheader header row for the current menu_subheader } else { // handle the rest of the items for the current menu_subheader } } etc... } 

再次,只是一个想法…