0

表格部分和 sortDescriptors 中有一些东西让我发疯。任何帮助都感激不尽 ;)

我正在寻找的只是在每个 self.fetchedResultsController.fetchedObjects 部分的底部显示一个“添加”行。我正在使用 sectionNameKeyPath 在我的表格视图中显示部分。到这里为止,一切都很完美。我已经在我的应用程序的其他部分实现了这种技术并且效果很好。

但是,当 FRC 没有返回数据并且核心数据没有返回任何实体时,就会出现问题。如果我尝试添加我的第一个托管对象,则应用程序会因以下错误而中断:

更新后表视图中包含的节数(1)必须等于更新前表视图中包含的节数(1),加上或减去插入或删除的节数(1插入,0已删除)。与用户信息(空)

到目前为止,这是我的代码:

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    if ([self.fetchedResultsController.fetchedObjects count] == 0) {
        return 1;
    }
   return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.

    if ([self.fetchedResultsController.fetchedObjects count] == 0) {
        return 1;
    }
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];

    return [sectionInfo numberOfObjects] + 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    if ([self.fetchedResultsController.fetchedObjects count] == 0 ) {

        static NSString *identificadorCelda2 = @"CeldaNuevoGasto";
        UITableViewCell *celda = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identificadorCelda2];
        if (celda == nil) {
            celda = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identificadorCelda2];
        }
        return celda;
    }

    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:indexPath.section];

    NSInteger nsection = [sectionInfo numberOfObjects];

    if (indexPath.row == nsection) {

        static NSString *identificadorCelda2 = @"CeldaNuevoGasto";
        UITableViewCell *celda = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identificadorCelda2];
        if (celda == nil) {
            celda = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identificadorCelda2];
        }        
        return celda;
    }

    static NSString *CellIdentifier = @"CeldaGasto";

    CeldaGastos *cell = (CeldaGastos *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = (CeldaGastos *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    } .....

肯定我做错了什么,但我想不通。我是否还需要修改 NSFetchedResultsController 委托方法以响应添加?或者它更容易。谢谢 ;)

更新

    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{

    NSInteger nsection = [self.fetchedResultsController.sections count];
    switch(type) {
        case NSFetchedResultsChangeInsert:
            if (nsection == 1 && [sectionInfo numberOfObjects] == 1) {
                    [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];

            }
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:

            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];

            if (!nsection)
                [self.tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}
4

1 回答 1

1

如果我正确理解您的情况,那么您确实也必须更改 NSFetchedResultsController 委托方法。

-insertSections:withRowAnimation:您是否使用NSFetchedResultsController 的一些委托回调中的表格视图方法将新部分插入表格视图?

我不确切知道您的 NSFetchedResultsControllerDelegate 的实现是什么,但例如逐步考虑这种情况:

  1. 最初,您没有获取任何实体,并且您的-numberOfSectionsInTableView:方法为您的“添加”行返回 1。

  2. 在您插入一个实体并且 NSFetchedResultsController 的委托接收到它的-controller:didChangeSection:atIndex:forChangeType:回调后,您可以在其中使用-insertSections:withRowAnimation:

  3. 表视图通过调用-numberOfSectionsInTableView:期望它重新运行增加 1 的值的方法来询问其数据源(因为您要插入 1 个新部分)。但是该方法仍然返回 1,因为不再考虑“添加”行。

这将导致您遇到的错误。

我想-deleteSections:withRowAnimation:在不再需要时调用删除“添加”行将解决您的问题。

于 2012-11-05T16:07:29.657 回答