【问题标题】:Touch event handled by multiple views由多个视图处理的触摸事件
【发布时间】:2012-01-12 07:48:39
【问题描述】:

我在UITableView 之上有一个UIView 的子类。我正在使用UITableView 来显示一些数据,同时我想覆盖一个跟随手指的动画(例如,留下痕迹)。

如果我做对了,我需要由UIView 子类和UITableView 处理触摸事件两者。我怎样才能做到这一点? 是否有可能在 UIView 子类上触发 touchesMoved,然后在 UITableView 上触发?

非常感谢您的帮助。

【问题讨论】:

    标签: ios touch touchesmoved touch-event uievent


    【解决方案1】:

    UITableView 将未处理的触摸事件中继到 UIView。 (谷歌“响应链”) UITableView Documentation

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

    1. touchesstart - 做初始化工作

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

    3. touchesend - 做剩下的事情

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回复,但我不确定我是否完全理解(特别是我不明白第一句话的意思)。我知道我可以在 UIView 中绘制轨迹,但我仍然需要将触摸事件“传递”到 UITableView(滚动、选择等)。对不起,如果我误解了。
    • 在 Objective-C 中,有一种叫做响应者链的东西。如果一个类不处理特定事件,则需要由其 Super 类处理。如果没有类处理该事件,则该事件最终由 NSObject 处理。因此,在您的情况下,由于 UIView 是 UITableView 的超类,您可以从 UIView 响应 UITableView 事件。
    • 如果我不是 Objective-C 方面的专家,我深表歉意...您能否举例说明这可能如何适用于可能的情况?我应该拥有手势的 UITableView 句柄,然后将它们传递给超类吗?怎么样?
    • 根本不处理UITableView中的事件,只处理UIView中的事件。
    • 你觉得我刚刚发布的答案怎么样?
    【解决方案2】:

    不,你不能含蓄地这样做。 Event Delivery章说

    窗口对象使用命中测试和响应链来查找 查看以接收触摸事件。在命中测试中,一个窗口调用 hitTest:withEvent: 在视图层次结构的最顶层视图上;这 方法通过递归调用 pointInside:withEvent: 在每个 在返回 YES 的视图层次结构中查看,继续向下 层次结构,直到找到触摸边界的子视图 发生。该视图成为命中测试视图。

    因此,当窗口找到被触摸的视图时,它返回 YES。当前只有一个视图可以处理触摸。

    但是,如果您需要为 UITableView 处理事件,请为 UIView 处理它!您可以使用– convertPoint、– convertRect 函数将触摸点转换为所需的坐标,将子视图添加到 UITableView 并根据坐标移动它,以及许多其他事情。

    【讨论】:

    • 这绝对可以。我可能在 UIView 子类“下”有多个元素......我是否需要对所有这些元素重复该过程?另外,我需要转换坐标以获得全局坐标,对吗?谢谢。
    • 我已经按照你的建议做了,但我不能再滚动 UITableView 了。你知道为什么吗?谢谢
    【解决方案3】:

    我解决这个问题的方法不是那么干净,但它确实有效。如果有更好的方法,请告诉我。

    我已经为我的自定义UIView 覆盖了hitTest,以便将触摸指向下面的UITableView。然后在UITableView 中,我通过touchesBegan、touchesMoved 等处理手势。在那里我还在UIView 上调用touchesBegan。

    以这种方式,触摸由两个视图处理。 我之所以不这样做(让UIView 的touchesBegan 调用UITableView 的touchesBegan)是因为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];
    }
    

    【讨论】:

    • 非常酷..我想在一段时间后做一些类似的事情。感谢发帖。
    • 我真的很喜欢这个。通过在子视图上手动调用 TouchesBegan 等,我尝试了很长时间以错误的方式进行操作。这个方法很好用!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2016-05-28
    • 2023-03-11
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    相关资源
    最近更新 更多