10

I'm trying to implement a AQGridView that uses a fetched results controller as its datasource.

I'm not particular sure how to handle the NSFetchedResultsController delegate methods using the grid view; namely the content changing ones. I understand how to use the FRC for the other grid view datasource delegates.

Could somebody point me in the right direction?

Anthony Wong
  • 103
  • 5
  • I see that there are InsertItemAtIndicies/DeleteItemAtIndicies methods that are provided, but they take an indexSet. Perhaps the question is how to translate an indexPath to an indexSet? – Anthony Wong Dec 01 '11 at 20:31
  • Just to say before you continue: AQGridView has very stupid limitations on updating gridView cell's and especially the count of the grid. You need to completely update your data source BEFORE any changes to the grid are made, otherwise it triggers a built-in exception. – CodaFi Dec 29 '11 at 18:45

3 Answers3

7

The result should look a little something like this:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
  [gridView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
       atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
  switch(type)
  {
    case NSFetchedResultsChangeInsert:
      break; 
    case NSFetchedResultsChangeDelete:
      break;
  }
}

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

  ChannelPageViewController *currentPageController, *destinationPageController;

  NSIndexSet * indices = [[NSIndexSet alloc] initWithIndex: indexPath.row];
  NSIndexSet *newIndices = [[NSIndexSet alloc] initWithIndex:newIndexPath.row];

  switch(type) {
      case NSFetchedResultsChangeInsert:
        [gridView insertItemsAtIndices:newIndices withAnimation:AQGridViewItemAnimationNone];
      break;

      case NSFetchedResultsChangeDelete:
        [gridView deleteItemsAtIndices:indices withAnimation:AQGridViewItemAnimationNone];
        break;

      case NSFetchedResultsChangeUpdate:
        [gridView reloadItemsAtIndices:indices withAnimation:AQGridViewItemAnimationNone];
        break;

      case NSFetchedResultsChangeMove:
        [gridView deleteItemsAtIndices:indices withAnimation:AQGridViewItemAnimationNone];
        [gridView insertItemsAtIndices:newIndices withAnimation:AQGridViewItemAnimationNone];
        break;
   }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
  [gridView endUpdates];
  if ([[frc fetchedObjects] count] == 1) {
    [gridView reloadData];
  }

}
Audun Kjelstrup
  • 1,430
  • 8
  • 13
0

Since AQGridView doesn't have sections, the best way to handle it would be to implement the NSFethcedresultscontroller delegate methods, and ignore any code for the cases related to updated sections. Also make sure you initialize the fetchrequest with no sectionNameKeyPath.

Then just follow the normal pattern for updating rows, but using NSIndexSet instead of NSIndexPath and InsertItemAtIndicies/DeleteItemAtIndicies instead of insertRowAtIndexPath/deleteRowAtIndexPath

I'm moving my AQGridView to CoreData now, so I'll post any updates to my answer as soon as I'm done...

Audun Kjelstrup
  • 1,430
  • 8
  • 13
-1

When the content changes I do a

[self.gridView reloadData];

or something like that in your case. It is exactly the same as with a tableview.

Christian Loncle
  • 1,584
  • 3
  • 20
  • 30
  • Yeah I figured as much, though I was looking for a way to use the insert/delete methods though to take advantage of the animations that are available. Using a `reloadData` just causes things to magically appear. – Anthony Wong Dec 28 '11 at 20:51
  • then you can mark this answer as right. It wil give you reputation too. – Christian Loncle Dec 29 '11 at 19:19