我有一个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的其他属性来处理手势的其他状态.有什么方法可以保证识别器总是会给我回到我分配给它的视图吗?
像UICollectionView和UITableView这样的视图将重用它们的单元格.如果您盲目添加一个gestureRecognizer,collectionView:cellForItemAtIndexPath:
每次重新加载单元格时都会添加一个新的.如果你滚动一下,你会在每个单元格上找到几十个gestureRecognizer.
理论上,除了多次调用gestureRecognizer的动作之外,这不会引起任何问题.但Apple在细胞重用方面使用了大量的性能优化,因此可能会出现某些问题.
解决问题的首选方法是将gestureRecognizer添加到collectionView中.
另一种方法是检查单元格上是否已有gestureRecognizer,如果没有则只添加新的.或者您使用找到的解决方案并删除prepareForReuse
单元格中的gestureRecognizer .当您使用后一种方法时,您应该检查是否删除(或测试)正确的方法.您不想删除系统为您添加的gestureRecognizers.(我不确定iOS目前是否使用此功能,但为了使您的应用能够证明未来,您可能希望坚持这种最佳做法.)