多个视图处理的触摸事件

9
我有一个UIView的子类,它在UITableView上方。我正在使用UITableView来显示一些数据,并且同时,我想叠加一个动画,跟随手指移动(例如,留下一条轨迹)。
如果我理解正确,我需要UIView子类和UITableView都处理触摸事件。我该怎么做呢? 是否可以在UIView子类上触发touchesMoved,然后在UITableView上触发?
非常感谢您的帮助。
3个回答

12
我解决这个问题的方法不太干净,但它有效。如果有更好的方法,请告诉我。
我重写了我的自定义UIView的hitTest方法,以便它将触摸指向下面的UITableView。然后在UITableView中,我通过touchesBegantouchesMoved等处理手势。在那里,我也调用了UIViewtouchesBegan方法。
这样就可以通过两个视图来处理触摸。 我之所以不采取另一种方式(即让UIViewtouchesBegan调用UITableViewtouchesBegan),是因为UITableView上的手势识别器将无法工作。 UIView子类的hitTest方法。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    // tview is the UITableView subclass instance
    CGPoint tViewHit = [tView convertPoint:point fromView:self];        
    if ([tView pointInside:tViewHit withEvent:event]) return tView;

    return [super hitTest:point withEvent:event];
}

UITableView子类的touchesBegan

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:touch.view];
    // ....

    // view is the UIView's subclass instance
    [view touchesBegan:touches withEvent:event];
}

非常酷!我已经有一段时间想做类似的事情了。感谢您的发布。 - hrishikeshp19
我真的很喜欢这个。我曾经长时间尝试使用错误的方式手动调用子视图上的TouchesBegan等等。这种方法非常棒! - Gandalf458

1

不能隐性地完成这个任务。 Event Delivery 章节解释道:

窗口对象使用命中测试与响应链寻找接收触摸事件的视图。在命中测试中,窗口对象在视图层级结构的最顶层视图上调用 hitTest:withEvent: 方法;此方法通过递归调用每个返回 YES 的视图的 pointInside:withEvent: 方法在视图层级结构中向下进行,直到找到所发生触摸事件所在矩形区域内的子视图。该视图成为命中测试视图。

因此,当窗口找到被触摸的视图时将返回 YES。当前只有一个视图能够处理触摸事件。

如果您需要处理UITableView的事件,那么请在UIView中处理它! 您可以使用-- convertPoint-- convertRect等函数将触摸点转换为所需的坐标,将子视图添加到UITableView中,并根据坐标移动它,还有许多其他操作。

这肯定可以。我的UIView子类可能有多个元素“在下面”...我需要为所有这些元素重复这个过程吗?另外,我需要转换坐标以获取全局坐标,对吗?谢谢。 - ios-lizard
我已经按照您的建议做了,但是我不能再滚动UITableView了。你知道为什么吗?谢谢。 - ios-lizard

0

UITableView将未处理的触摸事件传递给UIView。(Google“响应者链”){{link1:UITableView文档}}

因此,您只能在UIView中处理触摸事件。所以,在您的UIView中:

  1. touchesstart-执行初始化操作

  2. touchesmove-在UIView上绘制尾巴(使用计时器/延迟响应来禁用点,使其看起来像轨迹)

  3. touchesend-执行剩余操作

希望这可以帮助到您。


谢谢您的回复,但我不确定我完全理解(尤其是第一句话的意思我不明白)。我知道我可以在UIView中绘制轨迹,但我仍然需要“传递”触摸事件到UITableView(滚动、选择等操作)。如果我有误解,请原谅。 - ios-lizard
在Objective-C中,有一种叫做响应者链的东西。如果一个类不处理特定事件,那么这些事件需要由它的超类来处理。如果没有任何类处理该事件,最终该事件将由NSObject处理。因此,在您的情况下,由于UIView是UITableView的超类,您可以从UIView响应UITableView事件。 - hrishikeshp19
如果我对Objective-C不是特别熟悉,我很抱歉...您能否举个例子说明这如何适用于我的情况?我应该让UITableView处理手势,然后将它们传递给超类吗?怎么做? - ios-lizard
不要在UITableView中处理事件,只在UIView中处理事件。 - hrishikeshp19
你对我刚刚发布的答案有什么看法? - ios-lizard
您应该在UIView中处理事件。我猜这就是您所做的。 - hrishikeshp19

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接