我的手势识别器附加到错误的视图

 语笑嫣然小公主155 发布于 2023-01-11 08:03

我有一个UICollectionView,其中包含可以在屏幕上拖放的元素.我使用UILongPressGestureRecognizer来处理拖动.我将此识别器附加到我collectionView:cellForItemAtIndexPath:方法中的集合视图单元格中.但是,识别器的视图属性偶尔会返回UIView而不是a 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;
    }
}

longGestureActionBeganOn:withGesture被调用时cell实际上是UICollectionViewCell手势的其余部分完美地执行.如果不是,则当它尝试确定应该是单元格的索引路径时它会中断.

第一次发生休息

- (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的其他属性来处理手势的其他状态.有什么方法可以保证识别器总是会给我回到我分配给它的视图吗?

1 个回答
  • 像UICollectionView和UITableView这样的视图将重用它们的单元格.如果您盲目添加一个gestureRecognizer,collectionView:cellForItemAtIndexPath:每次重新加载单元格时都会添加一个新的.如果你滚动一下,你会在每个单元格上找到几十个gestureRecognizer.

    理论上,除了多次调用gestureRecognizer的动作之外,这不会引起任何问题.但Apple在细胞重用方面使用了大量的性能优化,因此可能会出现某些问题.

    解决问题的首选方法是将gestureRecognizer添加到collectionView中.

    另一种方法是检查单元格上是否已有gestureRecognizer,如果没有则只添加新的.或者您使用找到的解决方案并删除prepareForReuse单元格中的gestureRecognizer .当您使用后一种方法时,您应该检查是否删除(或测试)正确的方法.您不想删除系统为您添加的gestureRecognizers.(我不确定iOS目前是否使用此功能,但为了使您的应用能够证明未来,您可能希望坚持这种最佳做法.)

    2023-01-11 08:10 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有