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

Posted

技术标签:

【中文标题】UIView alpha 0 但仍接收触摸事件?【英文标题】:UIView alpha 0 but still receive touch events? 【发布时间】:2015-05-15 22:47:34 【问题描述】:

我试图隐藏一个 uiview 但仍然让它接收触摸事件。我将 alpha 设置为 0,如下所示:

mainView.alpha = 0.0

我也尝试将其设置为 true,但它没有做任何事情

mainView.userInteractionEnabled = true

问题是当我这样做时它不再接收触摸事件。如何使其能够接收触摸事件但有效隐藏?

【问题讨论】:

你可以的,是的;但最好重新考虑一下。如果用户看不到它,要求用户触摸它有什么意义?您应该重新考虑触摸处理的架构。 这是意料之中的。隐藏视图或 alpha 为 0 的视图永远不会收到事件。 @matt 这在某些情况下完全有意义。例如,我有一个应用程序,其中元素的表示需要很小,但我希望用户的交互区域更大,但只是不可见。表示元素的对象,与接收事件的不可见对象不同。因此,在某些特殊情况下,拥有一个捕获用户输入的透明对象可能是有意义的,而不会出现架构设计问题。 @nbloqs 同意,我实际上为此使用了透明覆盖。发表评论时我没有想到。 这正是我这样做的确切原因,因为触摸事件的触摸区域比原始元素所保证的要大。 【参考方案1】:

将您的UIViewbackgroundColor 设置为UIColor.clear

mainView.backgroundColor = .clear

【讨论】:

【参考方案2】:

有两种处理方法:

    最难的——不是在视图上设置 alpha,而是在其所有子视图上设置它并使视图中的所有内容不可见(例如,将背景更改为清晰的颜色)。

    简单的 - 让另一个视图处理事件。只需添加另一个具有相同位置和大小的透明视图(很容易使用约束)来处理事件。

顺便说一句,如果您查看文档中用于处理触摸事件的方法hitTest:withEvent:,它会说alpha 低于0.01 的视图不会收到触摸。

【讨论】:

是的,这适用于背景,但如果我隐藏它们,所有按钮都是相同的,它们不会接收事件。 2号的问题是有一个搜索栏。也许我应该提出一个新问题并重做我处理触摸的方式? @TylerRice 也许尝试用您的视图层次结构和您想要完成的任务来扩展您的问题?您的代码不起作用的原因很清楚。如果您提出问题,我们可以就解决方案提出建议。 @Gobe 还在,不过链接坏了。【参考方案3】:

隐藏视图的所有子视图并将backgroundColor设置为UIColor clearColor

【讨论】:

【参考方案4】:

您在寻找透明视图吗?

只需从 UIView 创建一个TransparantView 子类并复制以下代码。视图将是透明的,但仍会收到触摸。您可能需要更改一些代码,因为我的代码处理它的子视图。关键是重写 pointInside 来实现你的目标。

如果你只是想要一个透明视图,那么这个透明视图下的其他视图仍然可以得到通过透明视图传递的触摸事件,你不能在透明视图中添加任何子视图。

延伸阅读是学习响应者链。

@implementation TransparantView

- (id)initWithFrame:(CGRect)frame 
    self = [super initWithFrame:frame];
    return self;


-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
    for (UIView *view in self.subviews) 
        if (!view.hidden && view.alpha > 0 && view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event])
            return YES;
    
    return NO;

@end

更新:

当 alpha 设置为 0 时,ios 似乎不会向视图发送事件。但是,透明视图在屏幕上将没有任何内容,就好像它的 alpha=0。我已更新代码以修复错误

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
    for (UIView *view in self.subviews) 
        if (!view.hidden && view.alpha > 0 && view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event])
            return YES;
    
    if (!self.hidden && self.alpha >= 0.0 && self.userInteractionEnabled) 
        return YES;
     else
        return NO;

@end

【讨论】:

如何在视图控制器而不是视图中使用此方法? 我不关注。它只是 UIView 的一个子类,可以满足您的目标。把它当作普通的 UIView 使用,不需要显式调用任何方法。 pointInside 是 iOS 需要检查视图是否被触摸时调用的方法。 我已经更新了答案,用新代码试试。关键是您需要了解pointInside 的工作原理。 这个透明的视图似乎是一种很老套的方法,所以我想尝试跟踪触摸事件。你觉得呢?我还发布了一个新问题,因为我不确定如何在***.com/questions/30270526/… 上实现我所需要的,谢谢您的帮助! 我正忙于工作,所以不能很快回答新问题。我不同意这是一种 hacky 方式,因为这就是 OOP 所做的。您需要不时更改逻辑以满足您的需求。使用代码,您可以在视图透明时捕获触摸事件。我觉得你需要先阅读响应者链。另一种可能性是不建议您尝试在 iOS 上执行此操作。使用视图和控制器时有一些原则,您不想破坏它。如果真的需要破解,那就叫hacky

以上是关于UIView alpha 0 但仍接收触摸事件?的主要内容,如果未能解决你的问题,请参考以下文章

我可以创建一个完全透明的 UIView 来接收触摸吗?

以 UIScrollView 作为子类的 UIView 不接收触摸事件

在隐藏的 UIView 中接收触摸事件?

UIView alpha = 0 导致触摸被拖放到下面的视图

动画 UIView 的内容未接收到触摸事件

为啥 UIView 的这些自动布局约束会阻止 UIButton 子视图接收触摸事件?