首页 > 解决方案 > UITableView commitEditingStyle:用于展开和折叠部分

问题描述

我有一个带有展开和折叠部分的 UITableView。每个节标题实际上是每个节的索引 0 处的行。假设该部分包含六个项目,点击标题行(索引 0)会导致另外六行添加到该部分,总共七行。效果很好,看起来不错,展开和折叠平滑干净。该代码主要基于此处可以看到的内容:https ://www.cocoanetics.com/2011/03/expandingcollapsing-tableview-sections

其关键部分是在任何给定时间扩展的部分的索引都存储在 NSMutableIndexSet 中。因此,每次加载表视图时,它都会查询 self.expandedSections 以查看它是否应该加载所有行、显示文件夹内容,还是只加载包含文件夹名称的第一行。

当用户需要删除文件夹时,问题就来了。如果表视图包含索引高于被删除文件夹的任何扩展部分,我会遇到以下崩溃:

'无效更新:第 1 节中的行数无效。更新后现有节中包含的行数 (1) 必须等于更新前该节中包含的行数 (7),加上或减去从该部分插入或删除的行数(0 插入,0 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。

这个错误是不言自明的,事实上,苹果公司的某个人已经努力使它尽可能明确。但是,我找不到解决方法。删除代码如下所示:

if (editingStyle == UITableViewCellEditingStyleDelete)
{
    if (indexPath.row == 0) // we are deleting a folder
    {
        NSString *folderPath = [self.sectionHeaders objectAtIndex:indexPath.section];
        NSError *error = nil;
        if (![self.fileManager removeItemAtPath:folderPath error:&error]) [self.delegate alertForError:error];
        else
        {
            [self.sectionHeaders removeObjectAtIndex:indexPath.section]; // remove array reference to folder
            [self.expandedSections removeIndex:indexPath.section];

            // crashes if some other folder is displaying its contents
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
       }
    }
    else // we are deleting a file
    {
        etc...
    }
}

这在 tableView:commitEditingStyle:forRowAtIndexPath: 中调用:

任何建议都非常感谢!

标签: iosobjective-cuitableviewnsindexset

解决方案


解决了。虽然我从 self.expandedSections 中删除了已删除的部分,但我还需要更新集合中的其他值,如果它们高于被删除的值。我还需要更新表示文件夹内容的数组。

            [self.sectionHeaders removeObjectAtIndex:indexPath.section]; // remove array reference to folder
            [_arrayOfFolderContentsArrays removeObjectAtIndex:indexPath.section];

            // for each index in expandedSections, we need to reduce the value of those higher than the section being deleted
            NSMutableIndexSet *tempSet = [[NSMutableIndexSet alloc] init];
            [self.expandedSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
                // repopulate expandedSections without section that is being deleted
                if (idx > (NSUInteger)indexPath.section)
                {
                    idx--;
                    [tempSet addIndex:idx];
                }
                else if (idx < (NSUInteger)indexPath.section)
                {
                    [tempSet addIndex:idx];
                }
            } ];

            self.expandedSections = tempSet;

            // remove table view section
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];

推荐阅读