NSFetchResultController与UICollectionView问题与更新和删除操作上的索引/单元格有关 [英] NSFetchResultController with UICollectionView issue with indexes/cells on update and delete action

查看:51
本文介绍了NSFetchResultController与UICollectionView问题与更新和删除操作上的索引/单元格有关的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次使用UICollectionView时遇到了一些困难。尤其是使用来自 NSFetchResultController 的数据更新和删除单元格(这里将重点放在删除,希望是后来的原因)上。我已经在界面构建器中制作了一个自定义单元,作为故事板的一部分:

First time that I'm using UICollectionView, and I'm having some difficulties. Especially with updating and deleting cells (will focus on delete here, hopefully the came cause), with data from a NSFetchResultController. I have made a custom cell in in interface builder as part of a storyboard like this:

我有一个自定义的 UICollectionViewCell 子类,其内容如下属性:

I have a custom UICollectionViewCellsubclass with the following properties:

@property (strong, nonatomic) IBOutlet UIButton *deleteButton;
@property (strong, nonatomic) IBOutlet UITextField *textField;
@property (strong, nonatomic) IBOutlet UIView *containerView;
@property (strong, nonatomic) IBOutlet UIView *textFieldContainer;

在IB中,我将单元格类设置为自定义类,将元素连接到我的属性自定义类,并将标识符设置为 Cell

In IB I have set the cell class to my custom class, connected the elements to the properties of my custom class and set the identifier to Cell.

在我的集合视图视图控制器中,我设置了集合视图和fetchResultController以及诸如此类的相关方法:

In my Collection View view controller I set up the collection view and fetchResultController and relevant methods like this:

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return [[self.fetchedResultsController sections] count];
}

-  (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
    return [sectionInfo numberOfObjects];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NoteCollectionViewCell* cell = (NoteCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

- (void)configureCell:(NoteCollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    cell.deleteButton.tag = indexPath.row;
    [cell.deleteButton addTarget:self action:@selector(deleteNote:)  forControlEvents:UIControlEventTouchUpInside];

    [...]

    // I'm having some weird problem with this, se description below. 
    Note *note = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textField.tag = indexPath.row;
    cell.textField.delegate = self;
    cell.textField.text = note.name;
    [...]

#pragma mark - Fetched results controller

- (NSFetchedResultsController *)fetchedResultsController
{
    [Default FRC method]
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
   atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
  newIndexPath:(NSIndexPath *)newIndexPath
{
    UICollectionView *collectionView = self.collectionView;

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [collectionView insertItemsAtIndexPaths:@[newIndexPath]];
            break;

        case NSFetchedResultsChangeDelete:
            [collectionView deleteItemsAtIndexPaths:@[indexPath]];
            break;
        case NSFetchedResultsChangeUpdate:
            [self configureCell:(NoteCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
    }
}

我的删除操作如下:

- (void)deleteNote:(UIButton *)sender
{
    Note *note = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath  indexPathForItem:sender.tag inSection:0]];
    [[AppDelegate sharedAppDelegate].managedObjectContext deleteObject:note];
    [[AppDelegate sharedAppDelegate] saveContext];
}

我的更新操作( UITextField 委托方法)看起来像这样:

My update action (UITextField delegate method) looks like this:

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    Note *note = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForItem:textField.tag inSection:0]];
    note.name = textField.text;
    [[AppDelegate sharedAppDelegate] saveContext];
}

问题如下:


  • 删除按钮并不总是删除正确的单元格/对象。有时甚至根本不会删除对象/单元格。

  • 有时,当我删除对象时应用程序崩溃(SIGARBT错误)。

  • 有时文本显示在错误的文本字段中。

  • 有时,当我删除第0行并添加一些文本,然后添加按添加时,会添加一个具有与上一个(已删除)单元格相同的文本值的新单元格。

  • The delete button don't always delete the right cells/object. And sometime the object/cell won't be deleted at all.
  • Sometime the app crashes when I delete an object (SIGARBT error).
  • Sometimes the text shows up in the wrong textfield.
  • Sometimes when I delete row 0 with some text, then add press add, a new cell is added with the same text value as the previous (deleted) cell.

关于如何解决这些问题的任何想法都很棒!

Any ideas on how to solve these problems would be great!

更新

作为下面的注释,我的 deleteNote 操作中的此日志始终返回0 indexPath行。不知道这可能是原因。

As comment below, this log in my deleteNote action always returns 0 for indexPath row. Don't know if that could be the cause.

NSIndexPath *indexPath = [NSIndexPath indexPathForItem:sender.tag inSection:0];
NSLog(@"indexPath: %@. Row: %d", indexPath, indexPath.row);


推荐答案

我不知道这是否可以解释您的问题,但您调用

I don't know if that explains your problem, but you call

[cell.deleteButton addTarget:self action:@selector(deleteNote:)  forControlEvents:UIControlEventTouchUpInside];

每次 configureCell:atIndexPath:,以便在修改或重用单元格时将多个操作附加到
按钮。然后 deleteNote:对于一个触摸事件将被多次调用

each time in configureCell:atIndexPath:, so that multiple actions are attached to the button if a cell is modified or reused. Then the deleteNote: would be called more than once for one touch event.

,您可以检查 cell.deleteButton.tag 来查看按钮是否已附加操作,或者更好:

As a workaround, you could check cell.deleteButton.tag to see if an action has already been attached to the button, or better:


  • 在创建单元格后,将 NoteCollectionViewCell
    中的操作添加到该类中的本地操作中

  • 使用委托将操作转发到集合视图控制器。

这篇关于NSFetchResultController与UICollectionView问题与更新和删除操作上的索引/单元格有关的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆