如何使触摸事件通过 UIView(类似于 CSS 中的 pointer-events:none)?

Posted

技术标签:

【中文标题】如何使触摸事件通过 UIView(类似于 CSS 中的 pointer-events:none)?【英文标题】:How can I make touch events pass through a UIView (similar to pointer-events:none in CSS)? 【发布时间】:2014-02-28 06:46:10 【问题描述】:

在 CSS 中,pointer-events:none; 允许点击事件通过元素。我很好奇我是否可以在 ios 上的 Objective-C 中为UIViews 做类似的事情。

Here's a jsfiddle to an example of pointer-events: none.

我能否以某种方式为 a UIView 实现相同的行为 通过覆盖 hitTest:withEvent: 或者也许还有其他方法可以做这个?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

这是一个符合您最初直觉的方便实现:

#import "TouchTransparentView.h"

@implementation TouchTransparentView

-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
    id hitView = [super hitTest:point withEvent:event];
    if (hitView == self) 
        return nil;
     else 
        return hitView;
    


@end

Swift 版本,带有@IB 升级

import UIKit

@IBDesignable
class PassthroughTouchView: UIView 

    @IBInspectable var passthroughTouchEvents : Bool = false

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? 
        let hitView = super.hitTest(point, with: event)
        if hitView == self && passthroughTouchEvents == true 
            return nil;
         else 
            return hitView;
        
    

【讨论】:

【参考方案2】:

您要查找的内容通常称为“事件冒泡”。

您可以在此处参考 Apple 文档: https://developer.apple.com/documentation/uikit/understanding_event_handling_responders_and_the_responder_chain

所以你的基本直觉是正确的,你确实需要使用hitTest:withEvent:,但是你可以通过连接到响应者链来进一步定制东西。该部分有一个非常简洁的示例。

【讨论】:

链接失效,可以参考developer.apple.com/library/ios/documentation/EventHandling/…。 现在替换链接已经失效,这是一个从今天开始有效的链接:Understanding Responders and the Responder Chain 这是最新链接:Understanding Event Handling, Responders, and the Responder Chain【参考方案3】:

迅速:

import UIKit

class PassThroughView: UIView 

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? 

        let hitView = super.hitTest(point, with: event)

        if hitView == self 
            return nil
         else 
            return hitView
        
    

但是不得不这样做很糟糕......

【讨论】:

【参考方案4】:

如果您正在寻找类似 @​​987654321@ 的东西,我会使用

yourView.userInteractionEnabled = NO

它应该做基本相同的事情。

【讨论】:

这会杀死事件;他们无法通过孩子。这不是 OP 想要的。

以上是关于如何使触摸事件通过 UIView(类似于 CSS 中的 pointer-events:none)?的主要内容,如果未能解决你的问题,请参考以下文章

UIView alpha 0 但仍接收触摸事件?

使触摸在 UIView 子类中留下发光的痕迹

跨多个子视图处理触摸事件

获取 UIView 上的最后一个触摸事件

将触摸事件从覆盖 UIView 转发到 UIWebView / 如何从代码将触摸事件发送到 uiwebview

如何让 UIView 忽略触摸而不释放它?