2012-10-15 24 views
8

Ho una semplice applicazione basata su UICollectionView - una UICollectionView e un modello di dati basato su NSMutableArray per semplicità.Eliminazione di celle da UICollectionView tramite NSNotification

posso eliminare le cellule senza alcun problema attraverso il didSelectItemAtIndexPath: metodo delegato:

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

Tuttavia, sto cercando di aggiungere un opzione di eliminazione tramite un UIMenuController in una sottoclasse UICollectionViewCell che viene attivato tramite un UILongPressGestureRecognizer che tutto funziona benissimo e mi attivano con successo un NSNotification

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

prendo nella mia ViewController e chiamare il metodo seguente:

-(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]]; 
     } 
} 

E si blocca sui deleteItemsAtIndexPaths: chiamare

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

Ho controllato tutto evidente - come l'oggetto dalla NSNotification e indexPath creata dalla indexPathForCell: chiamata e tutto sembra tutto bene. Sembra che sto chiamando deleteItemsAtIndexPath: con le stesse informazioni in entrambe le posizioni, ma per qualche motivo fallisce quando passa attraverso la route di notifica.

Si tratta di informazioni presso l'indirizzo indicato nella errore:

(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) 

Forse il percorso dell'indice dopo l'aggiornamento essere nulla è significativo ...

Tutte le idee?

+0

In 'deleteCell:' 'si utilizza self.collectionViewOne' e' self.collectionView' - è di proposito? –

+0

scusa - era un errore di battitura. – melps

+0

Posso confermare che ciò accade anche quando si inseriscono nuovi elementi da una notifica. – Brett

risposta

25

ho trovato una soluzione grezza ma funzionante, ed ha addirittura controlla se l'azione è già implementata in una futura release (meglio di una categoria)

// 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: Aggiunto controllo per iOS5.
Edit2: Lo stiamo spedendo in molti progetti commerciali (http://pspdfkit.com) e funziona benissimo.

+1

Questa risposta ha funzionato come un fascino per me. Dovrebbe essere contrassegnato come la soluzione. –

+0

thxs, ha funzionato per me. A proposito, stavo ottenendo questo quando impostando una vista all'interno di una cella come prima risposta, e non c'è una tastiera visibile –

+0

Qualcuno ha un esempio minimo di ciò che causa questo? Sto riscontrando un arresto anomalo in un'altra app senza la visualizzazione della tastiera o la modifica del primo risponditore. –

0

È possibile passare il NSIndexPath della cella selezionata nel dizionario userInfo della notifica. È possibile impostarlo nella tag della cella personalizzata al momento della sua creazione.

+0

Ma non è un problema di NSIndexPath essere sbagliato, quindi non sono sicuro di ciò che sarebbe di aiuto. – melps

0

Ho avuto lo stesso problema. La mia app si arrestava in modo anomalo quando ho provato a inserire una cella nel mio UICollectionView dopo aver selezionato il testo in un UITextField inserito in una collectionViewCell. La mia correzione era di dare le dimissioni al primo risponditore prima che l'inserimento avvenisse. Dal momento che stavo usando un NSFetchedResultsController per gestire l'aggiornamento ho messo questo all'inizio del controllerWillChangeContent:

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

ho trovato findAndResignFirstResponderfrom this SO answer

Problemi correlati