全屏 UIView 子类作为面纱不消耗触摸事件
Posted
技术标签:
【中文标题】全屏 UIView 子类作为面纱不消耗触摸事件【英文标题】:Full-screen UIView subclass as veil not consuming touch events 【发布时间】:2011-03-04 20:30:16 【问题描述】:我有一个可以运行的标签栏应用。每个选项卡都是一个UINavigationController
,其根视图是某种UIViewController
,通常是UITableViewController
。
在应用程序中的某些情况下,我想显示一个全屏“面纱”,其中包含有关正在发生的事情的消息,直到某些操作完成。关键是要吞下 UI 上的任何触摸,这些触摸会远离操作开始的位置。
面纱是 UIView 的子类。该类有一个单例实例。显示时,我将其作为UITabBarController
视图的子视图插入。该视图出现在整个 UI 上,包括标签栏。太好了!
这就是问题所在。我可以点击选项卡并更改 UI。我所期望的是,我的面纱视图会吞噬这些触摸。
我已经在我的面纱类中实现了各种触摸Began|Ended|Moved|Canceled 方法(作为无操作方法),但触摸仍然被标签栏拾取,坦率地说,被任何对象下的任何地方拾取我碰巧碰到了。
我也尝试过覆盖许多其他方法,包括 nextResponder、hitTest:withEvent: 等,但均无济于事。
在这一点上我有点难过。我希望有人能给一些圣人的建议。 :-)
谢谢。
【问题讨论】:
【参考方案1】:修改框架类的视图层次结构是不安全的。只需将其添加为窗口本身的子视图,您会得到更好的服务。至于消费触摸,如果进行此更改不起作用,那么您还应该验证 userInteractionEnabled
在视图上设置为 YES。您不必实际实现任何与触摸相关的方法。
【讨论】:
@Kevin-Ballard:谢谢。因此,我按照您的建议实现了相同的视觉效果:将面纱插入为代表窗口的子视图。并且,面纱的userInteractionEnabled
标志设置为YES。我注释掉了我的触摸处理方法的空实现。触摸继续传递到底层视图。还有其他想法吗?
@MarkGranoff:我认为如果您将空实现留在原地,它也会失败?你把它插在窗口的根部?对于您的行为,我能想到的最可能的原因是,如果超级视图具有 UIGestureRecognizer,但如果您位于窗口的根目录,则情况并非如此。我唯一能想到的就是你的阿尔法。您是否在视图中设置了 alpha
属性?如果alpha
等于或小于0.05
,则触摸跳过视图。它应该设置为1
,并且您的视图应该没有背景颜色。
@Kevin-Ballard:是的,有或没有 null 实现,相同的行为。没有使用 UIGestureRecognizers,至少我没有明确表示。 alpha 属性已设置,但设置为 0.65。所以我将它设置为 1,并使用 clearColor 以便我可以看到可能发生的情况。仍然失败。顺便说一句,视图是用类似[[myApp delegate].window addSubview:[Veil theVeil]]
的代码插入的。这当然有效(我看到了面纱),而且我想不出另一种“正确的方式”来做到这一点。真的很奇怪。
@Kevin-Ballard:哦,我还为面纱视图设置了ExclusiveTouch 为YES,我认为这肯定可以解决问题,但它没有效果。
@MarkGranoff: setExclusiveTouch
实际上并没有按照你的想法去做。它与如何处理多个触摸事件有关,对单次触摸没有任何影响。【参考方案2】:
我也遇到了这个问题,并想出了一个 hacky 解决方案。在自定义 UIView 类的 init
中,创建一个无法命中的虚拟 UIView,例如 [[UIView alloc] initWithFrame:CGRectMake(-1, -1, 0, 0)]
。或者实际上,我认为任何未附加到窗口的 UIView 都有效。然后,在hitTest:withEvent:
中,让它为您感兴趣的区域之外的每个点返回虚拟视图。
【讨论】:
以上是关于全屏 UIView 子类作为面纱不消耗触摸事件的主要内容,如果未能解决你的问题,请参考以下文章