我创建了一个包含可点击部分的 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 部分。我添加了一个 tapGestureRecognizer 来触发对 tableview 的委托(delegate)回调。下面包括打开这些部分的完整方法。
- (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];
}
最佳答案
据我所知,问题是在返回已使用的剖面 View 时出现的。而不是:
- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section
{
return [self.sectionHeaderViews objectAtIndex:section];
}
如果我每次都创建一个新 View ,我不会有任何问题:
- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section{
SectionHeaderView *sectionHeaderView = [self.tableView dequeueReusableCellWithIdentifier:SectionHeaderView_NibName];
sectionHeaderView.textLabel.text = [NSString stringWithFormat:@"Section %d", section];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:sectionHeaderView action:@selector(handleTap:)];
[sectionHeaderView addGestureRecognizer:tapRecognizer];
sectionHeaderView.section = section;
sectionHeaderView.delegate = self;
return sectionHeaderView;
}
这可能是因为您正在使用 [self.tableView dequeueReusableCellWithIdentifier:SectionHeaderView_NibName]; 创建节标题并将它们保存在数组中,我认为 UITableViewCell 不是创建,但我不确定。您可能需要考虑前面的 UITableViewCell 用于部分 View ,而不是使用其他东西(可能是带有 UILabel 的 UIImageView)。或者您可以不将剖面 View 存储在数组中……按照您当前设置代码的方式,您不需要数组并且创建新 View 非常简单,您无需担心。
关于ios - insertRowsAtIndexPaths : with scrollToRowAtIndexPath: causes UITableView sections to be incorrectly hidden,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11515374/