空sortDescriptors和表视图部分

时间:2012-11-05 14:23:11

标签: iphone uitableview nsfetchedresultscontroller nssortdescriptor

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

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

然而,当FRC没有返回数据并且核心数据没有返回任何实体时,问题出现了。如果我尝试添加我的第一个托管对象,那么app就会出现以下错误:

  

更新后表视图中包含的部分数   (1)必须等于表中包含的部分数   更新前的视图(1),加上或减去部分的数量   插入或删除(插入1个,删除0个)。 with userInfo(null)

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

    - (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;
    }
}

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

  3. 在表格视图中插入新的部分
  4. 表视图通过调用-numberOfSectionsInTableView:方法询问其dataSource,期望它重新加载一个增加1的值(因为你插入了1个新节)。但该方法仍然返回1,因为不再考虑“添加”行。

  5. 这将导致您所遇到的错误。

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