简体   繁体   English

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

[英]Updating a UICollectionView when an item is added (Core Data), stuck on insertItemsAtIndexPaths

Ok, I'm really stuck here :/ In Apple's Collection View Programming Guide for inserting an item it says there are two steps : 好的,我真的很困在这里:/在Apple的Collection View编程指南中,要插入一个项目,它说有两个步骤:

  1. Update the data in your data source object. 更新数据源对象中的数据。
  2. Call the appropriate method of the collection view to insert or delete the section or item. 调用集合视图的适当方法以插入或删除节或项。

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. 我不知道要为insertItemsAtIndexPaths:参数添加什么。 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. 您可以在我的早期代码(cellForItemAtIndexPath)中看到,我在填充集合时正在修改单元格内按钮元素的属性。 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. 您似乎尚未实现任何NSFetchedResultsControllerDelegate方法。 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. NSFetchedResultsController的实例将通知其委托,以匹配与其提取请求匹配的对象集合。 It does so by calling the various NSFetchedResultsControllerDelegate methods on it's delegate. 通过在其委托上调用各种NSFetchedResultsControllerDelegate方法来实现。 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: 例如,如果将新对象插入分配NSManagedObjectContext获取请求匹配的获取结果控制器的NSManagedObjectContext ,则会调用以下NSFetchedResultsControllerDelegate方法:

controllerWillChangeContent: controllerWillChangeContent:

controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:

controllerDidChangeContent: 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. controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:是您在集合视图上调用insertItemsAtIndexPaths:方法的地方,以告诉它数据源中有新项目可用。 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. 您还应该实现其他NSFetchedResultsControllerDelegate方法。 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 在此之前,将所有数据self.fetchedResultsController

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 核心数据对象更改时更新uicollectionview - Updating uicollectionview when core data object changes 当标题在屏幕上时,IOS UICollectionView insertItemsAtIndexPaths崩溃 - IOS UICollectionView insertItemsAtIndexPaths crash when header is on screen UICollectionView insertItemsAtIndexPaths:引发异常 - UICollectionView insertItemsAtIndexPaths: throws exception ios UICollectionView中的ios NSIndexPath insertItemsAtIndexPaths - ios NSIndexPath insertItemsAtIndexPaths in UICollectionView UICollectionView insertItemsAtIndexPaths引发NSInternalInconsistencyException - UICollectionView insertItemsAtIndexPaths Throws NSInternalInconsistencyException UICollectionview insertItemsAtIndexPaths 停止滚动 - UICollectionview insertItemsAtIndexPaths stops scrolling UICollectionView insertItemsAtIndexPaths:引发错误 - UICollectionView insertItemsAtIndexPaths: raising error SwiftUI:添加核心数据项时更新选项卡栏徽章 - SwiftUI: Update Tab Bar Badge when Core Data item is added 如何使UICollectionView在将项目添加到顶部时不滚动 - How to make UICollectionView not scroll when and item is added to the top UICollectionView insertItemsAtIndexPaths:似乎重新加载collectionview或自动滚动到顶部 - UICollectionView insertItemsAtIndexPaths: seems to reload collectionview or autoscrolls to top
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM