2012-10-15 31 views
8

Mam prostą aplikację opartą na UICollectionView - jeden model danych oparty na UICollectionView i NSMutableArray dla uproszczenia.Usuwanie komórek z UICollectionView poprzez NSNotification

mogę usunąć komórki bez problemu poprzez didSelectItemAtIndexPath: metodę Delegat:

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

Jednak próbuję dodać opcję kasowania poprzez UIMenuController w UICollectionViewCell podklasy, który jest wyzwalane przez UILongPressGestureRecognizer który wszystko działa dobrze i skutecznie wyzwalać NSNotification

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

złapię go w moim ViewController i wywołać w następujący sposób:

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

I to wywala na deleteItemsAtIndexPaths call

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

Sprawdziłem wszystko oczywiste - jak obiekt z NSNotification i indexPath utworzonego z indexPathForCell: zadzwonić i wszystko wydaje się całkowicie w porządku. Wygląda na to, że nazywam deleteItemsAtIndexPath: z tymi samymi informacjami w obu miejscach, ale z jakiegoś powodu nie powiedzie się, gdy przechodzi przez trasę powiadomienia.

to info na adres podany w błąd:

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

Może ścieżka indeksu po aktualizacji jest null jest znacząca ...

jakieś pomysły?

+0

W 'deleteCell:' 'self.collectionViewOne' używasz i' self.collectionView' - Czy to celowo? –

+0

Przepraszam - to było jak literówka. – melps

+0

Mogę potwierdzić, że dzieje się tak również podczas wstawiania nowych elementów z powiadomienia. – Brett

Odpowiedz

25

znalazłem surowy ale pracuje obejścia, a nawet sprawdza, czy działania są już realizowane w przyszłej wersji (lepiej niż kategoria)

// 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: dodałem sprawdzanie iOS5.
Edycja2: Wysyłamy to w wielu komercyjnych projektach (http://pspdfkit.com) i działa świetnie.

+1

Ta odpowiedź zadziałała jak urok dla mnie. Powinien być oznaczony jako rozwiązanie. –

+0

thxs, pracował dla mnie. BTW, otrzymywałem wtedy ustawiając widok w komórce jako pierwszą odpowiedź i nie ma widocznej klawiatury –

+0

Czy ktoś ma minimalny przykład tego, co to powoduje? Mam awarię w innej aplikacji bez wyświetlania klawiatury lub zmiany pierwszej odpowiedzi. –

0

Można przekazać w komórce NSIndexPath wybranej komórki ze słownika userInfo powiadomienia. Możesz to ustawić w tag swojej niestandardowej komórki, gdy zostanie ona utworzona.

+0

Ale to nie jest kwestia nieprawidłowego działania NSIndexPath, więc nie jestem pewien, co by to mogło pomóc. – melps

0

Miałem ten sam problem. Moja aplikacja zawiesiłaby się, gdy próbowałem wstawić komórkę do mojego UICollectionView po wybraniu tekstu w obiekcie UITextField, który został umieszczony wewnątrz kolekcji collectionCell. Moja poprawka polegała na tym, aby zrezygnować z pierwszej odpowiedzi przed wprowadzeniem. Ponieważ używałem NSFetchedResultsController obsłużyć aktualizację kładę to na początku controllerWillChangeContent:

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

znalazłem findAndResignFirstResponderfrom this SO answer

Powiązane problemy