【问题标题】:Is it possible to decide which view the UITouch gets bound to?是否可以决定 UITouch 绑定到哪个视图?
【发布时间】:2012-05-11 18:20:42
【问题描述】:

我有几个 UIView,它们的形状有些复杂,我通过每个 UIView 的 drawRect: 方法绘制了这些形状。我保存了对路径的引用(通过 CGPath 属性),并在我的触摸方法中使用它来检测触摸是否实际上在路径或形状(CGPathContainsPoint)内。由于形状的原因,视图的某些区域是透明的(显然,任何不是方形/矩形的区域都将具有透明区域,假设视图的 backgroundColor 属性设置为 clearColor 或类似的)。

对于视图最终位于顶部或相互重叠的情况(经常发生),我正在测试触摸方法(touchesBegan 等)以查看触摸是否实际上在 CGPath 或形状内。如果触摸不在形状内,我会将触摸转发到下面的下一个视图,看看它是否反过来通过了该要求。

可悲的是(令我沮丧的是),这与实际绑定到视图的触摸行为不同。我已经以各种方式解决了这个问题,除了一个特别的问题。每个视图都使用 UIRotationGestureRecognizer。但是,如果触摸源自另一个视图的透明区域,并且该视图将该触摸转发到其下方的视图,则永远不会触发 UIGestureRecognizer。

我已经从我知道的各个角度看待这个问题。我试图想办法将触摸重新分配或绑定到适当的视图,但我不知道这是否可能。只要视图只是将触摸转发到另一个视图,触摸将保持绑定到首先收到触摸的原始视图。

我想知道您是否可以通过子类化 UIApplication 或 UIWindow 并覆盖 sendEvent:" 方法来执行此操作。我不确定 Apple 在这方面会给您什么控制权。我不能做任何可能的事情正在访问私有 API。我真的只需要一些方法来重新分配触摸,以便视图认为触摸属于它。

有什么想法吗?'

【问题讨论】:

    标签: ios uitouch uiresponder uievent


    【解决方案1】:

    您可以通过子类化 UIView 或子类化 UIGestureRecognizer 来做到这一点。

    继承 UIView

    通过继承 UIView(或其任何子类)并覆盖

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
    

    您可以决定哪些点被视为在您的视图内。对于路径之外的点,您只需返回 NO

    继承 UIGestureRecognizer

    通过继承 UIGestureRecognizer(或其任何子类)并覆盖

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    

    您可以决定手势识别器应该识别哪些触摸。对于路径之外的所有触摸,您应该调用(但不是子类)

    - (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event
    

    你自己。


    指向路径内?

    在任何一种情况下,您都需要知道这些点是否在您所说的存储路径内。

    如果路径已经存储为UIBezierPaths,您可以直接调用

    - (BOOL)containsPoint:(CGPoint)point
    

    在贝塞尔路径上。点或触摸可能需要通过调用转换为与路径相同的视图坐标

    - (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view
    

    - (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view
    

    在你看来。

    如果路径存储为 CGPath,您可以使用它创建 UIBezierPath

    [UIBezierPath bezierPathWithCGPath:CGPath]; 
    

    【讨论】:

    • 虽然这并没有完全回答问题,但它让我走上了正轨。在进一步研究后,我发现这篇博文完全回答了这个问题:bynomial.com/blog/?p=74 我接受了这个答案,因为这是一项很好的努力,帮助我弄清楚了我需要知道的内容。
    • 有什么我可以澄清的吗?
    • 因为每个视图都通过覆盖触摸方法(touchesBegan、moved 等)来“拦截”触摸,所以 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 从未发生过除非我触及视图之外,否则调用。但是通过我上面提供的链接,我能够覆盖底层子视图的 hitTest: 方法,然后使用 pointInside: 来确定它是否是有效的触摸。另外,虽然我确定您对“路径内的点”的意思很好?部分,这无关紧要,因为我说我已经在这样做了。再次感谢
    猜你喜欢
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多