How to refresh a UITableViewController or NSFetchedResultsController?

拟墨画扇 提交于 2019-11-29 18:41:50

问题


I have a little problem with my UITableViewController or NSFetchedResultsController. I am not sure which is the problem soure but I guess its the UITableViewController.

As I said I use a NSFetchedResultsController to fill my data into a UITableViewController. The data is sorted by date and is also displayed in sections by date-year, e.g. May 2010/June 2010/ and so on. This is displayed as the section header.

Now when I add new data, it automatically uses the current date as default, but if I want to use a date, that is currently not in the section list, e.g. April 2010 (currently May and June in the list), then this is not displayed correctly. Only when I quit the app and start it again it will show the new section headers and everything is fine.

So I somehow need to be able to refresh my list or update it. By just adding it to the context and changing it does not seem to update it.

Again, I am not sure what I need to update, if it is my NSFetchedResultsController object or the UITableViewController.

UPDATE #1:

I just figured that there is an exception in this method :

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];

}

This is where I move the data :

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

    UITableView *tableView = self.tableView;

    switch(type) 
    {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
        //  [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];

            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            // Reloading the section inserts a new row and ensures that titles are updated appropriately.
            [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }

}

This method is pretty much taken from the CoreDataBooks example from Apple. And this is the error :

Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. *** -[NSMutableArray removeObjectAtIndex:]: index 1 beyond bounds [0 .. 0] with userInfo (null)

And after that, the edit mode (where the delete button appears) does not work anymore.

Thanks.


回答1:


Ok, looks like I found a solution, I just skip these

[self.tableView beginUpdates];
[self.tableView endUpdates];

and always do this.

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{

[self.tableView reloadData];

}

I will obviously give this some more logic, since the problem only occures when I want to move my data in a section that does not exist before. Until someone can give me a real solution, I will go with this one.




回答2:


Adopting the fix by Apple in iPhoneCoreDataRecipes in version 1.2, the proper thing to do is to replace

 // Reloading the section inserts a new row and ensures that titles are updated appropriately.
 [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];

with

    [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];

(FileMerge is your friend!)

Note, there's another fix in version 1.2 that prevents erratic crashing when creating new entries. I had reported this and it was fixed within two weeks. I encourage you to file bug reports with Apple. They're far more responsive than you think, and you can expect to get the best possible fix.




回答3:


You need to implement the controller:didChangeSection:atIndex:forChangeType: delegate methods. In it, send insertSections:withRowAnimation:, deleteSections:withRowAnimation:, and reloadSections:withRowAnimation: messages to your table view depending on the reported change type.



来源:https://stackoverflow.com/questions/3077332/how-to-refresh-a-uitableviewcontroller-or-nsfetchedresultscontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!