在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上的
insert
或deleteRowsAtIndexPaths: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_headers
和menu_subheaders
将始终可见,只有项目将被显示/隐藏。
所以这里是我的想法(让我们看看是否可以解释得足够好):你可能有一个想法,每个menu_header
有多less个menu_header
(静态数或一个数组的元素个数),所以你可以添加一个每个menu_header(实际上只包含一行或一个标题)以及在这两者之间可以添加可扩展的部分( menu_subheaders
),可以像上面提到的答案中所示的那样进行pipe理。 而且,如果您想在先前展开的menu_subheader
上折叠另一个,则可以重置它的布尔值,然后使用reloadSections
方法重新加载。 你将不得不做一些计算menu_headers
和menu_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... }
再次,只是一个想法…