问题描述
为了简单起见,我有一个基于 UICollectionView 的简单应用程序 - 一个 UICollectionView 和一个基于 NSMutableArray 的数据模型.
I have a simple UICollectionView based app - one UICollectionView and a NSMutableArray based data model for simplicity.
我可以通过 didSelectItemAtIndexPath: 委托方法毫无问题地删除单元格:
I can delete cells with no problem via the didSelectItemAtIndexPath: delegate method:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
[self.data removeObjectAtIndex:[indexPath row]];
[self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
}
但是,我正在尝试通过 UICollectionViewCell
子类中的 UIMenuController
添加删除选项,该子类通过 UILongPressGestureRecognizer
触发工作正常,我成功触发 NSNotification
However, I'm trying to add a delete option via a UIMenuController
in a UICollectionViewCell
subclass which is triggered via a UILongPressGestureRecognizer
which all works fine and I successfully trigger an NSNotification
-(void)delete:(id)sender{
NSLog(@"Sending deleteme message");
[[NSNotificationCenter defaultCenter] postNotificationName:@"DeleteMe!" object:self userInfo:nil];
}
我在 ViewController 中捕获它并调用以下方法:
I catch it in my ViewController and call the following method:
-(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 上崩溃:调用
And it crashes on the deleteItemsAtIndexPaths: call
-[UICollectionViewUpdateItem action]: unrecognized selector sent to instance 0xee7eb10
我已经检查了所有明显的东西——比如来自 NSNotification 的对象和从 indexPathForCell: 调用创建的 indexPath,这一切看起来都很好.似乎我在两个地方都使用相同的信息调用 deleteItemsAtIndexPath:,但由于某种原因,它在通过通知路由时失败了.
I've checked everything obvious - like the object from NSNotification and the indexPath created from the indexPathForCell: call and it all seems totally fine. It seems like I'm calling deleteItemsAtIndexPath: with the same information in both places, but for some reason it fails when it goes via the notification route.
这是错误中给出的地址的信息:
This is the info at the address given in the error:
(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)
也许更新为空后的索引路径很重要……
Perhaps the index path after update being null is significant...
有什么想法吗?
推荐答案
我找到了一个粗略但可行的解决方法,它甚至会检查是否已经在未来的版本中实现了操作(比类别更好)
I found a crude but working workaround, and it even checks if action is already implemented in a future release (better than a category)
// 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),而且效果很好.
Added check for iOS5.
We're shipping that in lots of commercial projects (http://pspdfkit.com) and it works great.
这篇关于通过 NSNotification 从 UICollectionView 中删除单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!