I have a simple UICollectionView based app - one UICollectionView and a NSMutableArray based data model for simplicity.
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]];
}
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];
}
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]];
}
}
And it crashes on the deleteItemsAtIndexPaths: call
-[UICollectionViewUpdateItem action]: unrecognized selector sent to instance 0xee7eb10
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...
Any ideas?
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");
}
}
}
}
Edit: Added check for iOS5.
Edit2: We're shipping that in lots of commercial projects (http://pspdfkit.com) and it works great.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With