添加项目时更新UICollectionView(核心数据),卡在insertItemsAtIndexPaths上

时间:2014-09-12 19:55:59

标签: ios core-data uicollectionview collectionview

好吧,我真的被困在这里:/在Apple的Collection View Programming Guide中插入一个项目,它说有两个步骤:

  1. 更新数据源对象中的数据。
  2. 调用集合视图的相应方法以插入或删除节或项目。
  3. 我被困在第二个。我希望新项目出现在集合视图的开头。我不知道要为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 个答案:

答案 0 :(得分: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方法。使用批量更新进行集合视图更改不是必需的,可以轻松实现。

答案 1 :(得分:-1)

我也不能正确理解你的问题。但这对你有帮助,

从Core Data获取所有数据后

[self.collectionView reloadData];

在此之前将所有数据都放到self.fetchedResultsController