2014-09-12 3 views
1

Хорошо, я действительно застрял здесь:/В коллекции View Руководство по программированию от Apple для вставки элемента он говорит, есть два шага:Обновления UICollectionView при добавлении пункта (основные данные), застрял на insertItemsAtIndexPaths

  1. Обновите данные в объекте источника данных.
  2. Вызовите соответствующий метод представления коллекции, чтобы вставить или удалить раздел или элемент.

Я застрял на втором. Я хочу, чтобы новый элемент появился в начале представления коллекции. Я не знаю, что поставить для аргумента insertItemsAtIndexPaths:. Я знаю, что ему нужен массив объектов индекса, но я не знаю, как сказать ему, чтобы выбрать начало коллекции, поскольку это значение индекса, и я тоже смущен, как сказать ему что-нибудь еще. Вы можете видеть в моем предыдущем коде (cellForItemAtIndexPath). Я изменяю свойства элемента кнопки внутри ячейки при заполнении коллекции. Если бы я хотел изменить новый элемент при создании, как бы я это сделал? Я очень ценю любую помощь в этом, я чувствую, что здесь много не хватает, и я действительно ударяю о кирпичную стену.

@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]; 
} 

ответ

2

Вы, кажется, не реализовали любой из NSFetchedResultsControllerDelegate методы. Для функциональности, которую вы хотите, являетесь делегатом выбранного контроллера результатов.

Экземпляр NSFetchedResultsController проинформирует его делегата об изменениях в коллекции объектов, которые соответствуют запросу на выборку. Он делает это, вызывая различные методы NSFetchedResultsControllerDelegate на своем делетете. Например, если новый объект вставляется в NSManagedObjectContext назначенного контроллера надуманных результатов, который соответствует запросу выборки, называется следующие NSFetchedResultsControllerDelegate метод:

controllerWillChangeContent:

controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:

controllerDidChangeContent:

controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:, где вы бы назвали метод insertItemsAtIndexPaths: в представлении коллекции, чтобы сообщить ему, что в его источнике данных были доступны новые элементы. Это будет выглядеть так:

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

Очевидно, что реальный пример должен правильно обрабатывать другие типы изменений, это лишь иллюстративный пример. Вы также должны реализовать другие методы NSFetchedResultsControllerDelegate. Использование пакетных обновлений для изменений вида коллекции не требуется и может быть легко реализовано.

+0

Это приведет к сбою, например, если было добавлено более одного объекта. –

+0

quellish, большое вам спасибо за то, что нашли время, чтобы дать такой подробный ответ. Я попробовал это - только для опции NSFetchedResultsChangeInsert до сих пор - и это работает как шарм!Я добавлю остальные требования для всех методов делегатов после выходных и буду использовать этот метод для обновления представлений коллекции в будущем. Не могу вас поблагодарить! – Jared

-1

Я также не понимаю ваш вопрос правильно. Но это поможет вам,

После извлечения всех данных из основных данных,

[self.collectionView reloadData]; 

До этого поместить все данные в self.fetchedResultsController

+0

Hi BC_Dilum, когда я пытаюсь это сделать, приложение вылетает после запуска действия: «Недопустимое обновление: недопустимое количество элементов в разделе 0.» – Jared

Смежные вопросы