5

我有一个tableviewCell,用户可以在其中scroll水平。由于几乎scrollView涵盖了整个内容cell,因此如果用户单击.tableViewdidSelectRowcell

所以我想,我可以将触摸事件传递UIScrollViewcell,但仍然didSelectRow没有被调用。UIScrollView如果触摸不是拖动,我将子类化为仅传递触摸事件:

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event
{
    NSLog(@"touch scroll");
    // If not dragging, send event to next responder
    if (!self.dragging)
        [self.superview touchesEnded: touches withEvent:event];
    else
        [super touchesEnded: touches withEvent: event];
}

关于如何将点击传递给表格、调用委托方法并将滚动保持在scrollview?

4

5 回答 5

22

您实际上可以在没有子类化的情况下做到这一点UIScrollView。无论您有自定义单元格,还是在 中设置属性cellForRowAtIndexPathUITableView您都可以执行以下操作:

[cell.contentView addSubview:yourScrollView];
yourScrollView.userInteractionEnabled = NO;
[cell.contentView addGestureRecognizer:yourScrollView.panGestureRecognizer];

您可以这样做的原因是因为 scrollView 有自己的 panGestureRecognizer 可供程序员访问。因此,只需将其添加到单元格的视图中就会触发滚动视图的手势委托。

这种方法的唯一缺点是滚动视图的子视图无法接收任何触摸输入。如果你需要这个,你将不得不选择不同的方法。

于 2015-01-08T23:12:34.223 回答
7

我刚刚遇到了同样的问题。
在您的子类中确保包含完整的方法集:

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

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

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

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    if (!self.dragging)
        [self.superview touchesEnded: touches withEvent:event];
    else
        [super touchesEnded: touches withEvent: event];
}
于 2013-03-12T14:59:35.517 回答
1

选择的答案是正确的,但我根据我得到的错误更新了代码。

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    if (self.dragging) {
        [super touchesMoved:touches withEvent:event];
    } else {
        if ([self.delegate isKindOfClass:[UITableViewCell class]]) {
            [(UITableViewCell *)self.delegate touchesCancelled:touches withEvent:event];
        }

        [self.superview touchesMoved:touches withEvent:event];
    }
}

如果您self.delegate不是UITableViewCell,则将该属性替换为您的单元格的属性。

单元格需要在移动过程中检索取消触摸事件,以防止出现不希望的结果。它可以很容易地重现如下。

  • 突出显示单元格(假设滚动视图在整个单元格上,如果不突出显示滚动视图)
  • 当单元格突出显示时,拖动表格视图
  • 选择任何其他单元格,现在之前突出显示的单元格将检索didSelectCell状态

还有一点要提的是顺序很重要!如果在self.delegate之前没有调用,self.superview则突出显示的状态不会发生。

于 2014-03-05T06:13:14.710 回答
0

斯威夫特 3

scrollView.isUserInteractionEnabled = false
contentView.addGestureRecognizer(scrollView.panGestureRecognizer)
于 2017-05-24T08:39:52.933 回答
-1

尝试设置这个

_scrollView.canCancelContentTouches = NO

此外,部分转发触摸事件也很糟糕

于 2013-02-25T09:16:47.857 回答