ios - UITableView - 无项目标签 - 使用第三个单元格,如 Notes App - 插入第一条记录并删除最后一条记录时崩溃

标签 ios objective-c core-data uitableview

我想实现与在 iOS6 中使用笔记应用程序完成的相同行为,也许我不记得在 iOS7 中完成过相同的行为。

为了在第三个单元格中显示消息“No Notes”,我做得很好,但是当我添加第一条记录或删除最后一条记录时它崩溃了。

我不想使用表格页眉或页脚,我想像在 Notes 应用程序中那样使用。

类似这个问题 UITableView deleteRowsAtIndexPath crash when delete last record

所以问题是它在插入第一条记录或删除最后一条记录时崩溃。错误信息是一样的:-

CoreData:错误:严重的应用程序错误。在调用 -controllerDidChangeContent: 期间从 NSFetchedResultsController 的委托(delegate)捕获了一个异常。更新无效:第 0 节中的行数无效。更新 (1) 后现有节中包含的行数必须等于更新 (3) 前该节中包含的行数,加上或减去行数从该部分插入或删除的行数(1 插入,0 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。与用户信息(空)

我了解问题及其发生的原因,但我尝试了太多不同的方法来解决它,但我不知道如何解决。

请哪位好心人帮帮我。非常感谢。

- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
            if (self.myModel.count == 0)
            {
                return 3;
            }

            return self.myModel.count;
    }


    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
            UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Identifier" forIndexPath:indexPath];

            if (self.allNotes.count == 0)
            {
                cell = [self initilizeNoItemsCell:cell forIndexPath:indexPath];
            }
            else
            {
                cell = [self initilizeMyObjectCell:cell forIndexPath:indexPath];
            }

            return cell;
    }


    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
    {   
            [self.tableView beginUpdates];
    }

    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
    {
            switch(type)
            {
                    case NSFetchedResultsChangeInsert:

                        //crashes here when inserting the first record
                        [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                        break;

                    case NSFetchedResultsChangeDelete:
                        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                        break;

                    case NSFetchedResultsChangeUpdate:
                        [self.tableView reloadData];
                        break;

                    case NSFetchedResultsChangeMove:
                        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                        [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                        break;
            }
    }



- (void)tableView:(UITableView *)tableViewObj commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
        if (editingStyle == UITableViewCellEditingStyleDelete)
        {       
                //Crashes here also when deleting the last record
                [MyModel deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];

                NSError *error;
                if (![MyModel save:&error])
                {
                    NSLog(@"Failed to delete - error: %@", [error localizedDescription]);
                }
        }

        else if (editingStyle == UITableViewCellEditingStyleInsert)
        {

        }
}

如何在添加新记录之前去掉假的 3 行?

更新 1:-

插入第二条记录时。 CoreData:错误:严重的应用程序错误。在调用 -controllerDidChangeContent: 期间从 NSFetchedResultsController 的委托(delegate)捕获了一个异常。更新无效:第 0 节中的行数无效。更新 (2) 后现有节中包含的行数必须等于更新 (1) 前该节中包含的行数,加上或减去行数从该部分插入或删除的行数(0 插入,0 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。与用户信息(空)

删除一条记录(不是最后一条记录)时 CoreData:错误:严重的应用程序错误。在调用 -controllerDidChangeContent: 期间从 NSFetchedResultsController 的委托(delegate)捕获了一个异常。尝试将第 1 行插入第 0 节,但在使用 userInfo (null) 更新后第 0 节中只有 1 行

在得到 Paul 的回答后,它让我更接近了。当我尝试添加第二条记录时它崩溃了。在删除除最后一条记录以外的任何内容时也是如此。

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
        NSArray *emptyIndexPaths = [NSArray arrayWithObjects:
                                     [NSIndexPath indexPathForRow:0 inSection:0],
                                     [NSIndexPath indexPathForRow:1 inSection:0],
                                     [NSIndexPath indexPathForRow:2 inSection:0],
                                     nil];

        switch(type)
        {
            case NSFetchedResultsChangeInsert:                              
                if (self.allNotes.count == 1)
                {
                    [tableView beginUpdates];
                    [tableView deleteRowsAtIndexPaths:emptyIndexPaths withRowAnimation:UITableViewRowAnimationFade];
                    [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                    [tableView endUpdates];
                }            
                break;

            case NSFetchedResultsChangeDelete:

                if (self.allNotes.count == 1)
                {
                        [tableView beginUpdates];
                        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                        [tableView insertRowsAtIndexPaths:emptyIndexPaths withRowAnimation:UITableViewRowAnimationFade];
                        [tableView endUpdates];
                }
                break;


            case NSFetchedResultsChangeUpdate:
                [self.tableView reloadData];
                break;

            case NSFetchedResultsChangeMove:
                [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

        }
}

谢谢,

最佳答案

当您删除最后一行时,预期的行数将为 0(1 行 - 删除的 1 行 = 0),但您的 numberOfRowsInSection 将返回 3 - 因为 self.myModel.count 现在是0.

插入第一行时会发生类似的情况 - 4 是预期的行数 (3 + 1),但 1 是来自 numberOfRowsInSection 的值。

你需要——

NSArray *emptyIndexPaths = [NSArray arrayWithObjects:
                                 [NSIndexPath indexPathForRow:0 inSection:0],
                                 [NSIndexPath indexPathForRow:1 inSection:0],
                                 [NSIndexPath indexPathForRow:2 inSection:0],
                                 nil];

case NSFetchedResultsChangeInsert:
     [tableView beginUpdates];

     if (self.myModel.count == 1) {    
        [tableView deleteRowsAtIndexPaths:emptyIndexPaths withRowAnimation:UITableViewRowAnimationFade];    
     }     
     [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
     [tableView endUpdates];
  break;

  case NSFetchedResultsChangeDelete:
     [tableView beginUpdates];
     [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
     if (self.myModel.count == 0) {
         [tableView insertRowsAtIndexPaths:emptyIndexPaths withRowAnimation:UITableViewRowAnimationFade];
     }
     [tableView endUpdates];
  break;

关于ios - UITableView - 无项目标签 - 使用第三个单元格,如 Notes App - 插入第一条记录并删除最后一条记录时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22493962/

相关文章:

objective-c - NSButton 以编程方式列出或解除现有绑定(bind)

iphone - 如何在 Core Data 中分配相关对象?

iphone - 为什么我需要在核心数据项目中使用原始访问器方法?

xcode - PFQuery 没有获取对象 ID

ios - 更改 UIControlState.Highlighted 上的 UIButton backgroundColor?

ios - 获取 "next"索引的 NSIndexPath?

objective-c - Shell 脚本调用错误

objective-c - 在另一个 plist 文件中引用 info.plist 中的配置变量

ios - 如何使用 Core Data 中的数据填充 TextField 并更新更改?

ios - 迁移到 iOS VoIP 推送通知