【发布时间】:2014-06-08 19:20:46
【问题描述】:
我有一个 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 特有的其他属性用于手势的其他状态。有什么方法可以保证识别器总是将我分配给它的视图返回给我?
【问题讨论】:
-
问题可能与单元格重用有关,如果要显示一个单元格,您的代码最终会在每个单元格中使用多个手势识别器。从理论上讲,这应该只触发多次动作,而不是混淆视图。无论如何,我会推荐add the gestureRecognizer to the collectionView。
-
@MatthiasBauch 我在
prepareForReuse方法中删除了手势识别器,以防止多次添加识别器,它似乎解决了我的问题。如果您想根据您的评论做出回答,我会继续并将其标记为解决方案。
标签: ios objective-c uigesturerecognizer