Ios 我的手势识别器连接到错误的视图

Ios 我的手势识别器连接到错误的视图,ios,objective-c,uigesturerecognizer,Ios,Objective C,Uigesturerecognizer,我有一个UICollectionView,其中的元素可以在屏幕上拖放。我使用UILongPress手势识别器来处理拖动。我将此识别器附加到我的collectionView:cellForItemAtIndexPath:方法中的集合视图单元格。但是,识别器的view属性偶尔会返回UIView,而不是UICollectionViewCell。我需要一些仅在UICollectionViewCell上的方法/属性,当返回UIView时,我的应用程序会崩溃 为什么连接到单元格的识别器会返回普通UIView

我有一个UICollectionView,其中的元素可以在屏幕上拖放。我使用UILongPress手势识别器来处理拖动。我将此识别器附加到我的
collectionView:cellForItemAtIndexPath:
方法中的集合视图单元格。但是,识别器的view属性偶尔会返回
UIView
,而不是
UICollectionViewCell
。我需要一些仅在UICollectionViewCell上的方法/属性,当返回UIView时,我的应用程序会崩溃

为什么连接到单元格的识别器会返回普通UIView

附加识别器 处理手势 我使用带有switch语句的方法来分派长按的不同状态

- (void)longGestureAction:(UILongPressGestureRecognizer *)gesture {
    UICollectionViewCell *cell = (UICollectionViewCell *)[gesture view];
    switch ([gesture state]) {
        case UIGestureRecognizerStateBegan:
            [self longGestureActionBeganOn:cell withGesture:gesture];
            break;
        //snip
        default:
            break;
    }
}
如果
单元格
实际上是一个
UICollectionViewCell
,则调用
longGestureActionBeganOn:With手势
,手势的其余部分将完美执行。如果不是,则在尝试确定单元格的索引路径时会中断

首次发生断裂
我还将UICollectionViewCell特有的其他属性用于手势的其他状态。是否有某种方法可以保证识别器始终将我分配给它的视图返回给我?

像UICollectionView和UITableView这样的视图将重用它们的单元格。如果在
collectionView:cellForItemAtIndexPath:
中盲目添加手势识别器,则每次重新加载单元格时都会添加一个新的手势识别器。如果你稍微滚动一下,你会在每个单元格上找到几十个手势识别器

理论上,除了多次调用手势识别器的动作外,这不会导致任何问题。但苹果在单元重用上使用了大量的性能优化,所以可能会有什么东西把事情搞砸了

解决这个问题的首选方法是改为

另一种方法是检查单元格上是否已有手势识别器,如果没有,则只添加一个新的手势识别器。或者使用找到的解决方案,并在单元格的
prepareforeuse
中删除手势识别器。
当您使用后一种方法时,您应该检查是否删除(或测试)了正确的方法。您不想删除系统为您添加的手势识别器。(我不确定iOS目前是否使用此功能,但为了使您的应用程序能够为未来提供支持,您可能希望坚持此最佳实践。)

我遇到了与长触摸相关的类似问题。 我最后做的是覆盖UICollectionViewCell.PrepareForReuse并取消附加到我的视图的UIGestureRecognitors。所以每次我的手机被回收,一个长时间的新闻发布会就会被取消


问题可能与单元格重用有关,如果要显示单元格,则在代码中,每个单元格都会有多个GestureRecognitor。从理论上讲,这只会多次触发动作,而不会混淆观点。无论如何,我建议改为。@MatthiasBauch我在
prepareforeuse
方法中删除了手势识别器,以防止多次添加识别器,它似乎解决了我的问题。如果您想从您的评论中得出答案,我将继续并将其标记为解决方案。检查方式:如果([cell.GestureRecognitors count]){//Recognitor(s)已在单元格中找到}
- (void)longGestureAction:(UILongPressGestureRecognizer *)gesture {
    UICollectionViewCell *cell = (UICollectionViewCell *)[gesture view];
    switch ([gesture state]) {
        case UIGestureRecognizerStateBegan:
            [self longGestureActionBeganOn:cell withGesture:gesture];
            break;
        //snip
        default:
            break;
    }
}
- (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
    }
}