Ok, I'm really stuck here :/ In Apple's Collection View Programming Guide for inserting an item it says there are two steps :
I am stuck on the second one. I want the new item to appear at the start of the collection view. I do not know what to put for the insertItemsAtIndexPaths: argument. I know that it wants an Array of index objects, but I do not know how to tell it to choose the start of the collection as it's index value and am also confused how to tell it anything else. You can see in my earlier code (cellForItemAtIndexPath) I am modifying the properties of a button element within the cell upon populating the collection. If I wanted to modify the new item upon creation, how would I do that? I really appreciate any help on this, I feel I am missing a lot here and am really hitting a brick wall.
@implementation RepsCollectionViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Error : %@", error);
abort();
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Collection view data source
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> secInfo = [self.fetchedResultsController.sections objectAtIndex:section];
return [secInfo numberOfObjects];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
RepCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
Rep *rep = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.repButton.pressed = [rep.completed boolValue];
cell.repButton.indexPath = indexPath;
return cell;
}
#pragma mark - Fetched Results Controller
-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Rep" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"dateTimeCreated" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
_fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
#pragma mark - IBActions
- (IBAction)addRep:(id)sender {
[NSEntityDescription insertNewObjectForEntityForName:@"Rep" inManagedObjectContext:self.managedObjectContext];
[self.collectionView performBatchUpdates:^{
[self.collectionView insertItemsAtIndexPaths:WHAT TO PUT HERE?];
} completion:nil];
}
You don't seem to have implemented any of the NSFetchedResultsControllerDelegate
methods. For the functionality you want, being the delegate of the fetched results controller is key.
An instance of NSFetchedResultsController
will inform it's delegate of changes to the collection of objects that match it's fetch request. It does so by calling the various NSFetchedResultsControllerDelegate
methods on it's delegate. For example, if a new object is inserted into the NSManagedObjectContext
assigned to the fetched results controller that matches the fetch request, the following NSFetchedResultsControllerDelegate
methods are called:
• controllerWillChangeContent:
• controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
• controllerDidChangeContent:
controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
is where you would call the insertItemsAtIndexPaths:
method on the collection view, to tell it that new items were available in it's data source. This would look like:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UICollectionView *collection = self.collectionView;
switch(type) {
case NSFetchedResultsChangeInsert:
[collection insertItemsAtIndexPaths:@[newIndexPath] ];
break;
}
}
Obviously, a real example should correctly handle the other change types, this is just an illustrative example. You should also implement the other NSFetchedResultsControllerDelegate
methods. Using batch updates for collection view changes is not required and can be implemented easily.
I also don't understand your question correctly. But this will help you,
After fetching all the data from Core Data,
[self.collectionView reloadData];
Before that put all the data to self.fetchedResultsController
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.