[英]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.