bea*_*ain 5 cocoa-touch uitableview uikit ios
我创建了一个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];
Run Code Online (Sandbox Code Playgroud)
只有一个问题 - 所选部分下面的部分是隐藏的.第一个屏幕截图显示了tableview的外观.第二个屏幕截图显示了它的实际外观.

如果向上滚动(所以隐藏的部分在屏幕外),然后向下滚动,隐藏的部分将被带回(再次可见).我猜测为什么会发生这种情况如下:
插入/删除动画scrollToRowAtIndexPath与TableView 同时发生并且令人困惑.如果我没有完成scrollToRowAtIndexPath第3和第4部分就会出现在屏幕外 - 所以tableView仍然认为它们是在屏幕外.UITableview将屏幕外的单元格/部分隐藏为优化.如果我请scrollToRowAtIndexPath与dispatch_after用2秒钟,然后第3及4被正确显示.
所以我想我知道为什么会这样,但我不知道如何修复/覆盖这个UITableview优化.实际上,如果我scrollViewDidEndScrollingAnimation在此函数中实现然后添加断点,则应用程序会正确显示第3和第4部分(这就是我第一次进行屏幕截图).但是一旦继续这个功能,细胞就会消失.
完整的项目可以在这里下载
其他实现细节:Sections是合法的UITableView部分.我添加了一个tapGestureRecognizer,用于触发对tableview的委托回调.下面包含打开这些部分的整个方法.
- (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];
}
Run Code Online (Sandbox Code Playgroud)
据我所知,返回已经使用过的剖面视图时会出现问题.代替:
- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section
{
return [self.sectionHeaderViews objectAtIndex:section];
}
Run Code Online (Sandbox Code Playgroud)
如果我每次创建一个新视图,我都没有问题:
- (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;
}
Run Code Online (Sandbox Code Playgroud)
这可能是因为您正在使用[self.tableView dequeueReusableCellWithIdentifier:SectionHeaderView_NibName];创建节标题并在数组中保留它们,我不认为UITableViewCell是为其创建的,但我不确定.您可能需要考虑前面的UITableViewCell用于剖面视图,而是使用其他东西(可能是带有UILabel的UIImageView).或者你不能将剖面视图存储在一个数组中...你目前设置代码的方式,你不需要数组并创建一个新视图是微不足道的,你不需要担心它.
@AaronHayman 的回答有效(而且 IMO 的接受和赏金应该交给他,就目前而言 - 这只是不适合评论!),但我会走得更远 - 你根本不应该使用单元格作为部分标头,并且您不应该使用出队机制来基本上加载笔尖。
部分标题视图不应该是单元格,使用它们代替常规视图可能会产生不可预见的效果,特别是如果它们被取消队列 - 当您这样做时,表格会保留这些可重用单元格的列表,并回收它们当它们离开屏幕但您的部分标题不可重复使用时,您每个部分都有一个。
在您的示例项目中,我将 SectionHeaderView 的超类更改为普通 UIView,并将您的createSectionHeaderViews方法更改为直接从那里的笔尖加载:
NSMutableArray *sectionHeaderViews = [[NSMutableArray alloc] init];
UINib *headerNib = [UINib nibWithNibName:SectionHeaderView_NibName bundle:nil];
for (int i = 0; i < 5; i++)
{
SectionHeaderView *sectionHeaderView = [[headerNib instantiateWithOwner:nil options:nil] objectAtIndex:0];
sectionHeaderView.textLabel.text = [NSString stringWithFormat:@"Section %d", i];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:sectionHeaderView action:@selector(handleTap:)];
[sectionHeaderView addGestureRecognizer:tapRecognizer];
sectionHeaderView.section = i;
sectionHeaderView.delegate = self;
[sectionHeaderViews addObject:sectionHeaderView];
}
self.sectionHeaderViews = sectionHeaderViews;
Run Code Online (Sandbox Code Playgroud)
我还从您的 viewDidLoad 中注释掉了重用寄存器行。这可以防止节标题消失。
| 归档时间: |
|
| 查看次数: |
2868 次 |
| 最近记录: |