簡體   English   中英

我的手勢識別器附加到錯誤的視圖

[英]My gesture recognizer is attached to the wrong view

我有一個UICollectionView,其中包含可以在屏幕周圍拖放的元素。 我使用UILongPressGestureRecognizer來處理拖動。 我將此識別器附加到我的collectionView:cellForItemAtIndexPath:方法中的集合視圖單元格中。 但是,識別器的view屬性有時會返回UIView而不是UICollectionViewCell 我需要一些僅在UICollectionViewCell上的方法/屬性,並且當返回UIView時,我的應用程序崩潰。

附加到單元格的識別器為什么會返回普通的UIView?

附加識別器

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{
    EXSupplyCollectionViewCell *cell = (EXSupplyCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:cell action:nil];
    longPressRecognizer.delegate = self;
    [cell addGestureRecognizer:longPressRecognizer];
    return cell;
}

處理手勢

我使用帶有switch語句的方法來分派長按的不同狀態。

- (void)longGestureAction:(UILongPressGestureRecognizer *)gesture {
    UICollectionViewCell *cell = (UICollectionViewCell *)[gesture view];
    switch ([gesture state]) {
        case UIGestureRecognizerStateBegan:
            [self longGestureActionBeganOn:cell withGesture:gesture];
            break;
        //snip
        default:
            break;
    }
}

如果cell實際上是UICollectionViewCell ,則在調用longGestureActionBeganOn:withGesture ,其余手勢將完美執行。 如果不是,則在嘗試確定應為單元格的索引路徑時會中斷。

第一次出現中斷

- (void)longGestureActionBeganOn:(UICollectionViewCell *)cell withGesture:(UILongPressGestureRecognizer *)gesture
{
    NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell]; // unrecognized selector is sent to the cell here if it is a UIView
    [self.collectionView setScrollEnabled:NO];
    if (indexPath != nil) {
        // snip
    }
}

我還使用UICollectionViewCell特有的其他屬性來處理手勢的其他狀態。 有什么方法可以確保識別器始終將我分配給它的視圖還給我?

諸如UICollectionView和UITableView之類的視圖將重用其單元格。 如果您在collectionView:cellForItemAtIndexPath:盲目添加了一個actionRecognizer,則每次重新加載單元格時都會添加一個新的。 如果滾動一下,最終每個單元格上都會有數十個手勢識別器。

從理論上講,這不會造成任何問題,除了多次調用gestureRecognizer的動作。 但是,Apple在單元重用上使用了性能優化,因此某些東西可能會混亂。

解決該問題的首選方法是將gestureRecognizer添加到collectionView中

另一種方法是檢查單元格上是否已經有一個actionRecognizer,如果不存在則僅添加一個新的。 或者,您可以使用找到的解決方案, prepareForReuse在單元格的prepareForReuse中刪除gestureRecognizer。 使用后一種方法時,應檢查是否已刪除(或測試)正確的方法。 您不想刪除為您添加的手勢識別系統。 (我不確定iOS當前是否使用此功能,但為了將來為您的應用做證明,您可能希望遵循此最佳做法。)

我有一個與長觸摸有關的類似問題。 我最終要做的是重寫UICollectionViewCell.PrepareForReuse並取消附加到我的視圖的UIGestureRecognizers。 因此,每次我的牢房被回收時,長按事件都將被取消。

看到這個答案

暫無
暫無

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

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