簡體   English   中英

通過NSNotification從UICollectionView中刪除單元格

[英]Deleting cells from UICollectionView via NSNotification

我有一個簡單的基於UICollectionView的應用程序 - 一個UICollectionView和一個基於NSMutableArray的數據模型,為簡單起見。

我可以通過didSelectItemAtIndexPath:delegate方法刪除沒有問題的單元格:

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

不過,我試圖通過添加刪除選項UIMenuControllerUICollectionViewCell子類,可以通過觸發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:call上崩潰了

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

我已經檢查了所有明顯的東西 - 比如來自NSNotification的對象和從indexPathForCell:call創建的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)

也許更新后的索引路徑為空是重要的...

有任何想法嗎?

我發現了一個粗略但有效的解決方法,它甚至會檢查在將來的版本中是否已經實施了操作(優於某個類別)

// 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檢查。
編輯2:我們在許多商業項目( http://pspdfkit.com )中發布了它,並且效果很好。

您可以在通知的userInfo字典中傳入所選單元格的NSIndexPath 您可以在創建自定義單元格的tag時將其設置。

我遇到過同樣的問題。 當我在UITextField選擇文本后,我嘗試將單元格插入到我的UICollectionView時,我的應用程序會崩潰。該文檔位於collectionViewCell中。 我的解決方法是在插入發生之前辭職第一響應者。 因為我使用NSFetchedResultsController來處理更新,所以我把它放在controllerWillChangeContent:的開頭controllerWillChangeContent:

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

從這個SO答案找到了findAndResignFirstResponder

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM