Ios insertRowsAtIndexPaths:带有ScrollToRowatineXpath:会导致UITableView节被错误隐藏

Ios insertRowsAtIndexPaths:带有ScrollToRowatineXpath:会导致UITableView节被错误隐藏,ios,cocoa-touch,uitableview,uikit,Ios,Cocoa Touch,Uitableview,Uikit,我创建了一个UITableview,其中包含可单击的部分。当你点击它们时 它们“扩展”以显示其中的细胞 单击的部分将滚动到视图的顶部 我计算所有IndExpath以插入/删除必要的单元格,然后使用以下代码插入它们: [self.tableView beginUpdates]; [self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation]; [self.tableView deleteRow

我创建了一个UITableview,其中包含可单击的部分。当你点击它们时

  • 它们“扩展”以显示其中的细胞
  • 单击的部分将滚动到视图的顶部 我计算所有IndExpath以插入/删除必要的单元格,然后使用以下代码插入它们:

    [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的外观。第二个屏幕截图显示了它的实际外观

    如果向上滚动(使隐藏部分在屏幕外),然后向下滚动,则隐藏部分将返回(再次可见)。我对发生这种情况的原因的猜测如下:

    插入/删除动画与ScrollToRowatineXpath同时发生,这会混淆TableView。如果我没有做
    ScrollToRowatineXpath
    3和4部分,那么它们可能已经脱离了屏幕,因此tableView仍然认为它们脱离了屏幕。UITableview作为优化隐藏屏幕外的单元格/分区。如果我在之后用
    dispatch\u调用
    scrollToRowatinedexpath
    并持续2秒,则第3节和第4节将正确显示

    所以我想我知道为什么会发生这种情况,但我不知道如何修复/覆盖这个UITableview优化。实际上,如果我实现了
    ScrollViewDiEndScrollingAnimation
    ,然后在此函数中添加一个断点,应用程序将正确显示第3节和第4节(这就是我获得第一个屏幕截图的原因)。但是一旦继续进行这个功能,细胞就会消失

    完整的项目可以下载


    其他实现详细信息:节是合法的UITableView节。我添加了一个TapGestureRecognitor,它触发对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];
    }
    
    -(无效)sectionHeaderView:(sectionHeaderView*)sectionHeaderView SectionOpen:(NSInteger)SectionOpen
    {
    //打开
    sectionHeaderView.numRows=默认numRows;
    sectionHeaderView.selected=是;
    NSMUTABLEARRY*pathsToOpen=[[NSMUTABLEARRY alloc]init];
    对于(int i=0;i
    据我所知,返回已使用的剖面视图时会出现问题。而不是:

    - (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section
    {
        return [self.sectionHeaderViews objectAtIndex:section];
    }
    
    如果每次都创建一个新视图,我不会有任何问题:

    - (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\u NibName]
    创建节头并在数组中保留它们,我不认为UITableViewCell是为此创建的,但我不确定。您可能需要考虑前面的UITabeVIEW单元格视图,而不是使用其他的(可能是UIIVIEVIEW和UIABEL)。或者,您不能将剖面视图存储在数组中……按照您当前设置代码的方式,您不需要数组,创建新视图非常简单,您不需要担心。

    @AaronHayman的答案很有效(在我看来,接受和赏金应该归他所有,就目前的情况而言-这不适合评论!),但我想进一步说-你根本不应该使用单元格作为节头,也不应该使用出列机制来加载nib

    节头视图不应该是单元格,使用它们代替常规视图可能会产生不可预见的效果,特别是当它们被取消使用时——当您这样做时,表格会保留这些可重用单元格的列表,当它们离开屏幕时会回收它们,但您的节头是不可重用的,每个节都有一个

    在您的示例项目中,我将SectionHeaderView的超类更改为普通UIView,并将您的
    createSectionHeaderViews
    方法更改为直接从NIB加载:

    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;
    
    NSMutableArray*sectionHeaderViews=[[NSMutableArray alloc]init];
    UINib*headerNib=[UINib-nibWithNibName:SectionHeaderView\u-NibName bundle:nil];
    对于(int i=0;i<5;i++)
    {
    SectionHeaderView*SectionHeaderView=[[headerNib实例化所有者:nil选项:nil]对象索引:0];
    sectionHeaderView.textLabel.text=[NSString stringWithFormat:@“Section%d”,i];
    UITapGestureRecognizer*tapRecognizer=[[UITapGestureRecognizer alloc]initWithTarget:sectionHeaderView操作:@selector(handleTap:)];