UITableView:删除带有动画的部分 [英] UITableView: deleting sections with animation

查看:43
本文介绍了UITableView:删除带有动画的部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新

我在下面发布了我对此问题的解决方案作为答案.它采用了与我的第一次修订不同的方法.

I have posted my solution to this problem as an answer below. It takes a different approach from my first revision.

原始问题我之前在 SO 上问过一个我认为解决了我的问题的问题:

Original Question I previously asked a question on SO that I thought solved my issues:

如何处理不可见行删除期间的行.(UITableViews)

但是,从 UITableView 中删除部分时,我现在又遇到了类似的问题.(当我改变表格中的部分/行数时,它们重新出现).

However, I now have similar problems again when removing sections from a UITableView. (they resurfaced when I varied the number of sections/rows in the table).

在我因为帖子的剪切长度而失去你之前,让我把问题说清楚,你可以阅读尽可能多的提供答案.

Before I lose you because of the shear length of my post, let me state the problem clearly, and you can read as much as you require to provide an answer.

问题:

如果从 UITableView 批量删除行和部分,应用程序有时会崩溃.这取决于表的配置以及我选择删除的行和节的组合.

If batch deleting rows AND sections from a UITableView, the application crashes, sometimes. It depends on the configuration of the table and the combination of rows and sections I choose to remove.

日志说我崩溃了,因为它说我没有正确更新数据源和表:

The log says I crashed because it says I have not updated the datasource and the table properly:

Invalid update: invalid number of rows in section 5.  The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted).

现在,在你写下明显的答案之前,我向你保证我确实已经从数据源中正确地添加和删除了行和节.解释很长,但你会在下面找到它,按照方法.

Now quickly, before you write the obvious answer, I assure you I have indeed added and deleted the rows and sections properly from the dataSource. The explanation is lengthy, but you will find it below, following the method.

因此,如果您仍然感兴趣......

So with that, if you are still interested…

处理删除部分和行的方法:

- (void)createFilteredTableGroups{

    //index set to hold sections to remove for deletion animation
    NSMutableIndexSet *sectionsToDelete = [NSMutableIndexSet indexSet];
    [sectionsToDelete removeIndex:0];


    //array to track cells for deletion animation
    NSMutableArray *cellsToDelete = [NSMutableArray array];

    //array to track controllers to delete from presentation model
    NSMutableArray *controllersToDelete = [NSMutableArray array];

    //for each section
    for(NSUInteger i=0; i<[tableGroups count];i++){

        NSMutableArray *section = [tableGroups objectAtIndex:i];

        //controllers to remove
        NSMutableIndexSet *controllersToDeleteInCurrentSection = [NSMutableIndexSet indexSet];
        [controllersToDeleteInCurrentSection removeIndex:0];
        NSUInteger indexOfController = 0;

        //for each cell controller
        for(ScheduleCellController *cellController in section){

            //bool indicating whether the cell controller's cell should be removed
            NSString *shouldDisplayString = (NSString*)[[cellController model] objectForKey:@"filteredDataSet"];
            BOOL shouldDisplay = [shouldDisplayString boolValue];

            //if it should be removed
            if(!shouldDisplay){

                NSIndexPath *cellPath = [self indexPathOfCellWithCellController:cellController]; 

                //if cell is on screen, mark for animated deletion
                if(cellPath!=nil)
                    [cellsToDelete addObject:cellPath];

                //marking controller for deleting from presentation model
                [controllersToDeleteInCurrentSection addIndex:indexOfController];                

            }
            indexOfController++;
        }

        //if removing all items in section, add section to removed in animation
        if([controllersToDeleteInCurrentSection count]==[section count])
            [sectionsToDelete addIndex:i];

        [controllersToDelete addObject:controllersToDeleteInCurrentSection];

    }


    //copy the unfiltered data so we can remove the data that we want to filter out
    NSMutableArray *newHeaders = [tableHeaders mutableCopy];
    NSMutableArray *newTableGroups = [[allTableGroups mutableCopy] autorelease];


    //removing controllers
    int i = 0;
    for(NSMutableArray *section in newTableGroups){
        NSIndexSet *indexesToDelete = [controllersToDelete objectAtIndex:i];
        [section removeObjectsAtIndexes:indexesToDelete];
        i++;
    }

    //removing empty sections and cooresponding headers
    [newHeaders removeObjectsAtIndexes:sectionsToDelete];
    [newTableGroups removeObjectsAtIndexes:sectionsToDelete];

    //update headers
    [tableHeaders release];
    tableHeaders = newHeaders;

    //storing filtered table groups
    self.filteredTableGroups = newTableGroups;


    //filtering animation and presentation model update
    [self.tableView beginUpdates];
    tableGroups = self.filteredTableGroups;
    [self.tableView deleteSections:sectionsToDelete withRowAnimation:UITableViewRowAnimationTop];
    [self.tableView deleteRowsAtIndexPaths:cellsToDelete withRowAnimation:UITableViewRowAnimationTop];
    [self.tableView endUpdates];


    //marking table as filtered
    self.tableIsFiltered = YES; 


}

<小时>

我的猜测:

问题似乎是这样的:如果您查看上面我列出每个部分中单元格数量的位置,您会看到第 5 部分似乎增加了 1.但是,事实并非如此.原来的第 5 节实际上已被删除,取而代之的是另一节(具体来说,它是旧的第 10 节).

The problem seems to be this: If you look above where I list the number of cells in each section, you will see that section 5 appears to increase by 1. However, this is not true. The original section 5 has actually been deleted and another section has taken its place (specifically, it is old section 10).

那为什么表格视图似乎没有意识到这一点呢?它应该知道我删除了旧部分并且不应该期望现在位于旧部分索引处的新部分受已删除部分的行数约束.

So why does the table view seem not to realize this? It should KNOW that I removed the old section and should not expect a new section that is now located at the old section's index to be bound by the deleted section's number of rows.

希望这是有道理的,写出来有点复杂.

Hopefully this makes sense, it is a little complicate to write this out.

(请注意,此代码以前使用不同数量的行/节.此特定配置似乎给它带来了问题)

(note this code worked before with a different number of rows/sections. this particular configuration seems to give it issues)

推荐答案

我以前遇到过这个问题.您正在尝试删除一个部分中的所有行,然后删除现在为空的部分.但是,仅删除该部分就足够(并且适当).其中的所有行也将被删除.这是我的项目中处理删除一行的一些示例代码.它需要确定是否应该从一个部分中只删除这一行,或者如果它是该部分中最后剩余的行,则删除整个部分:

I’ve run into this problem before. You are trying to delete all rows from a section and then, in addition, that now empty section. However, it is sufficient (and proper) to remove that section only. All rows within it will be removed as well. Here is some sample code from my project that handles deletion of one row. It needs to determine whether it should remove only this row from a section or delete the entire section if it is the last remaining row in that section:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        // modelForSection is a custom model object that holds items for this section.
        [modelForSection removeItem:[self itemForRowAtIndexPath:indexPath]];

        [tableView beginUpdates];

        // Either delete some rows within a section (leaving at least one) or the entire section.
        if ([modelForSection.items count] > 0)
        {
            // Section is not yet empty, so delete only the current row.
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
        }
        else
        {
            // Section is now completely empty, so delete the entire section.
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] 
                     withRowAnimation:UITableViewRowAnimationFade];
        }

        [tableView endUpdates];
    }
}

这篇关于UITableView:删除带有动画的部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆