【发布时间】:2012-07-17 02:48:51
【问题描述】:
我创建了一个带有可点击部分的 UITableview。当你点击它们时,
- 它们“扩展”以显示其中的单元格
- 单击的部分滚动到视图的顶部。
我计算所有索引路径以插入/删除必要的单元格,然后使用以下代码插入它们:
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation];
[self.tableView deleteRowsAtIndexPaths:pathsToClose withRowAnimation:deleteAnimation];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:[pathsToOpen objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
只有一个问题 - 所选部分下方的部分是隐藏的。第一个屏幕截图显示了 tableview 的外观。第二个屏幕截图显示了它的实际外观。
如果您向上滚动(因此隐藏部分在屏幕外)然后向下滚动,隐藏部分将被带回(再次可见)。我对为什么会发生这种情况的猜测如下:
插入/删除动画与scrollToRowAtIndexPath 同时发生,这使TableView 感到困惑。如果我没有完成scrollToRowAtIndexPath 第 3 和第 4 节将在屏幕外 - 所以 tableView 不知何故仍然认为它们在屏幕外。 UITableview 隐藏了屏幕外的单元格/部分作为优化。如果我在 2 秒内使用 dispatch_after 调用 scrollToRowAtIndexPath,则第 3 和第 4 部分将正确显示。
所以我想我知道为什么会这样,但我不知道如何修复/覆盖这个 UITableview 优化。实际上,如果我实现 scrollViewDidEndScrollingAnimation 然后在此函数中添加断点,应用程序会正确显示第 3 和第 4 部分(这就是我获得第一个屏幕截图的方式)。但是一旦继续这个功能,细胞就会消失。
完整项目可以下载here
其他实现细节:节是合法的 UITableView 节。我添加了一个触发对 tableview 的委托回调的 tapGestureRecognizer。下面是打开这些部分的整个方法。
- (void)sectionHeaderView:(SectionHeaderView *)sectionHeaderView sectionOpened:(NSInteger)sectionOpened
{
// Open
sectionHeaderView.numRows = DefaultNumRows;
sectionHeaderView.selected = YES;
NSMutableArray *pathsToOpen = [[NSMutableArray alloc] init];
for (int i = 0; i < sectionHeaderView.numRows; i++)
{
NSIndexPath *pathToOpen = [NSIndexPath indexPathForRow:i inSection:sectionOpened];
[pathsToOpen addObject:pathToOpen];
}
// Close
NSMutableArray *pathsToClose = [[NSMutableArray alloc] init];
if (openSectionHeader)
{
for (int i = 0; i < openSectionHeader.numRows; i++)
{
NSIndexPath *pathToClose = [NSIndexPath indexPathForRow:i inSection:openSectionHeader.section];
[pathsToClose addObject:pathToClose];
}
}
// Set Correct Animation if section's already open
UITableViewRowAnimation insertAnimation = UITableViewRowAnimationBottom;
UITableViewRowAnimation deleteAnimation = UITableViewRowAnimationTop;
if (!openSectionHeader || sectionOpened < openSectionHeader.section)
{
insertAnimation = UITableViewRowAnimationTop;
deleteAnimation = UITableViewRowAnimationBottom;
}
openSectionHeader.numRows = 0;
openSectionHeader.selected = NO;
openSectionHeader = sectionHeaderView;
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation];
[self.tableView deleteRowsAtIndexPaths:pathsToClose withRowAnimation:deleteAnimation];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:[pathsToOpen objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
【问题讨论】:
-
我认为你最好使用Apple提供的MVC。您所要做的就是在数据源中添加/删除数据,并且不要触摸 tableview 行
-
请在问题中包含更多您的项目,而不是期待下载 - 例如,您如何计算添加/删除的索引路径,以及您的“Section X”事物部分标题还是它们只是单元格?如果它不那么依赖于下载您的项目,它将成为一个更好的独立问题。
-
我认为你的猜测也是正确的。您可以尝试在滚动结束委托方法中重新加载行吗?
-
@jrturton 感谢您的反馈。我在问题中包含了更多的实现细节。我还将项目的链接制作为更易于下载的 zip。我实际上已经尝试过重新加载 tableview 并且没有任何帮助。
标签: ios cocoa-touch uitableview uikit