为什么UICollectionView在滚动它的单元格的scrollView之后不再调用didSelectItemAtIndexPath?

时间:2014-06-19 07:44:14

标签: ios uiscrollview uicollectionview uicollectionviewcell uiresponder

我正在使用UICollectionView来展示一些产品。在自定义UICollectionViewCell中,有一个自定义UIScrollView,其中有一些图像允许用户进行快速预览。

要将点按手势从UIScrollView转发到UICollectionViewCell,我会覆盖与触摸相关的方法,如下所示:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        NSLog(@"Began ==>");
        [self.nextResponder touchesBegan:touches withEvent:event];
    }
    else {
        [super touchesBegan:touches withEvent:event];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        NSLog(@"Moved ==>");
        [self.nextResponder touchesMoved:touches withEvent:event];
    }
    else {
        [super touchesMoved:touches withEvent:event];
    }

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        NSLog(@"Ended ==>");
        [self.nextResponder touchesEnded:touches withEvent:event];
    }
    else {
        [super touchesEnded:touches withEvent:event];
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        NSLog(@"Cancelled ==>");
        [self.nextResponder touchesCancelled:touches withEvent:event];
    }
    else {
        [super touchesCancelled:touches withEvent:event];
    }
}

有时它在某些情况下不起作用。例如,当第一次加载UICollectionView时,可以在点击时调用didSelectItemAtIndexPath方法,但经过一些滚动或点击后,即使您尝试重新加载{,也不再调用该方法{1}},它仍然无效。

我尝试使用UICollectionView的触摸方式记录消息,触摸&事件被转发。但是,如果单元格获得手势,为什么会调用UICollectionViewCell didSelectItemAtIndexPath

非常感谢任何建议。

更新: 1.从{nib文件加载UICollectionView

3 个答案:

答案 0 :(得分:0)

如果您要定位特定对象,那么使用nextResponder并不是一个好主意。正如您刚刚目睹的那样,响应者链可以改变,您可能并不总是得到您期望的对象。为什么会发生这种情况可能有多种原因,但无论如何你应该在这种情况下使用更可靠的方法。

由于UIScrollViewUICollectionViewCell的子视图,您可以直接将事件传递给您的超级视图[self.superview touchesMoved:touched withEvent:event];当您执行此操作时,您需要牢记视图层次结构并且可能不得不打电话给superview的超级视图来到达单元格。

此外,我不建议使用触摸来拦截用户交互。我强烈建议使用UIGestureRecognizers,因为它将提供更好的更一致的功能。

答案 1 :(得分:0)

你应该总是调用超级方法。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    NSLog(@"Began ==>");
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];
    NSLog(@"Moved ==>");
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    NSLog(@"Ended ==>");
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    NSLog(@"Cancelled ==>");
}

答案 2 :(得分:0)

实际上这是因为self.dragging的理解。 转发点按手势的正确方法如下:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.nextResponder touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.nextResponder touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging) {
        [self.nextResponder touchesEnded:touches withEvent:event];
    }
    else {
        [super touchesEnded:touches withEvent:event];
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.nextResponder touchesCancelled:touches withEvent:event];
}