我第一次使用 UICollectionView,我遇到了一些困难。尤其是更新和删除单元格(这里将重点关注删除,希望是原因),来自NSFetchResultController
. 我在界面生成器中制作了一个自定义单元格,作为故事板的一部分,如下所示:
我有一个UICollectionViewCell
具有以下属性的自定义子类:
@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
.
在我的集合视图视图控制器中,我设置了集合视图和 fetchResultController 以及相关方法,如下所示:
- (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
委托方法)如下所示:
- (void)textFieldDidEndEditing:(UITextField *)textField
{
Note *note = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForItem:textField.tag inSection:0]];
note.name = textField.text;
[[AppDelegate sharedAppDelegate] saveContext];
}
问题如下:
- 删除按钮并不总是删除正确的单元格/对象。有时对象/单元格根本不会被删除。
- 有时,当我删除对象时应用程序崩溃(SIGARBT 错误)。
- 有时文本显示在错误的文本字段中。
- 有时,当我用一些文本删除第 0 行,然后添加按添加时,会添加一个新单元格,其文本值与前一个(已删除)单元格相同。
关于如何解决这些问题的任何想法都会很棒!
更新
正如下面的评论,我的deleteNote
操作中的这个日志总是为 indexPath 行返回 0。不知道会不会是这个原因。
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:sender.tag inSection:0];
NSLog(@"indexPath: %@. Row: %d", indexPath, indexPath.row);