8

为了简单起见,我有一个简单的基于 UICollectionView 的应用程序 - 一个 UICollectionView 和一个基于 NSMutableArray 的数据模型。

我可以通过 didSelectItemAtIndexPath: 委托方法毫无问题地删除单元格:

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    [self.data removeObjectAtIndex:[indexPath row]];
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
}

但是,我正在尝试通过 aUIMenuControllerUICollectionViewCell子类中添加一个删除选项,该选项是通过 a 触发的UILongPressGestureRecognizer,一切正常,我成功触发了NSNotification

-(void)delete:(id)sender{
      NSLog(@"Sending deleteme message");
      [[NSNotificationCenter defaultCenter] postNotificationName:@"DeleteMe!" object:self userInfo:nil];
}

我在 ViewController 中捕获它并调用以下方法:

-(void)deleteCell:(NSNotification*)note{
       MyCollectionViewCell *cell = [note object];
       NSIndexPath *path = nil;
       if((path = [self.collectionView indexPathForCell:cell]) != nil){
           [self.data removeObjectAtIndex:[path row]];
           [self.collectionView deleteItemsAtIndexPaths:@[path]];
       }
}

它在 deleteItemsAtIndexPaths 上崩溃:调用

-[UICollectionViewUpdateItem action]: unrecognized selector sent to instance 0xee7eb10

我已经检查了所有明显的东西——比如来自 NSNotification 的对象和从 indexPathForCell: 调用创建的 indexPath ,这一切看起来都很好。似乎我在两个地方都使用相同的信息调用 deleteItemsAtIndexPath:,但是由于某种原因,它在通过通知路由时失败了。

这是错误中给出的地址的信息:

(lldb) po 0xee7eb10
(int) $1 = 250080016 <UICollectionViewUpdateItem: 0xee7eb10> index path before update (<NSIndexPath 0x9283a20> 2 indexes [0, 0]) index path after update ((null)) action (delete)

也许更新为空后的索引路径很重要......

有任何想法吗?

4

3 回答 3

25

我找到了一个粗略但可行的解决方法,它甚至可以检查未来版本中是否已经实施了操作(比类别更好)

// Fixes the missing action method when the keyboard is visible
#import <objc/runtime.h>
#import <objc/message.h>
__attribute__((constructor)) static void PSPDFFixCollectionViewUpdateItemWhenKeyboardIsDisplayed(void) {
    @autoreleasepool {
    if ([UICollectionViewUpdateItem class] == nil) return; // pre-iOS6.
    if (![UICollectionViewUpdateItem instancesRespondToSelector:@selector(action)]) {
            IMP updateIMP = imp_implementationWithBlock(^(id _self) {});
            Method method = class_getInstanceMethod([UICollectionViewUpdateItem class], @selector(action));
            const char *encoding = method_getTypeEncoding(method);
            if (!class_addMethod([UICollectionViewUpdateItem class], @selector(action), updateIMP, encoding)) {
                NSLog(@"Failed to add action: workaround");
            }
        }
    }
}

编辑:添加了对 iOS5 的检查。
Edit2:我们在许多商业项目(http://pspdfkit.com)中都提供了它,而且效果很好。

于 2012-12-20T16:49:56.510 回答
0

您可以在通知字典中传入NSIndexPath所选单元格的。userInfo您可以在tag创建自定义单元格时将其设置在自定义单元格中。

于 2012-11-07T03:41:47.007 回答
0

我遇到过同样的问题。在我选择了放在 collectionViewCellUICollectionView中的文本后,当我尝试将一个单元格插入我的应用程序时,我的应用程序会崩溃。UITextField我的解决方法是在插入发生之前辞去第一响应者的职务。因为我使用 aNSFetchedResultsController来处理更新,所以我把它放在了开头controllerWillChangeContent:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [[UIApplication sharedApplication].keyWindow findAndResignFirstResponder];
    ...
}

findAndResignFirstResponder 从这个 SO 答案中找到

于 2013-07-22T08:43:27.337 回答