【问题标题】:Preventing unhandled touch events on a child view controller from passing through to container view防止子视图控制器上未处理的触摸事件传递到容器视图
【发布时间】:2018-03-14 08:58:08
【问题描述】:

我有一个容器视图控制器来管理它自己的全屏内容视图,并附加了几个手势识别器。子视图控制器可以覆盖在屏幕的一部分上;它的根视图是一个提供不透明背景颜色的 UIView,它被一个 UIScrollView 覆盖,而 UIScrollView 又包含堆栈视图等复杂的视图层次结构。

在子视图中滚动以及任何用户与其子视图的交互都可以正常工作。我遇到的问题是滚动视图本身(即不在其任何子视图内)上的任何点击或其他非滚动手势都通过它后面的空 UIView 并由根视图上的手势识别器意外处理父(容器)控制器。我希望这些触摸被孩子的背景视图所吞噬,以便它们被忽略/取消。

我的第一个想法是在子 VC 上覆盖 nextResponder 以返回 nil,假设这会阻止触摸事件传递到父视图。那里没有成功,所以我尝试覆盖子控制器上的触摸处理方法(touchesBegan: 等),但它们从未被调用。然后我将一个简单的 UIView 子类替换为我的子控制器的根视图,同样在那里尝试了这两种方法。再次为 nextResponder 返回 nil 无效,并且 touch 方法永远不会被调用。

我的响应链看起来完全按照我的预期设置:滚动视图 --> 子 VC 的根视图 --> 子 VC --> 父根视图 --> 父 VC。这让我认为我的控制器包含设置正确,并让我怀疑父级根视图上的手势识别器以某种我不理解的方式战胜了响应者链。

这看起来应该很容易。我错过了什么?谢谢!

【问题讨论】:

  • 图形表示你的东西会有帮助,或者演示项目:),或者几行代码
  • 确保您“替换”为子控制器根视图的 UIView 已启用用户交互设置为 true
  • 感谢@SandeepBhandari,我在使用普通 UIView 和使用我的子类时都启用了用户交互。我尝试关闭它(认为这可能是防止触摸沿着链向上传播所需要的),但这也会扼杀其所有子视图(我的滚动视图等)的用户交互。
  • @4bar :尝试实施 hitTest,正如我在我的回答中所发布的那样:) 那应该可以帮助你
  • @4bar :看起来很有趣。将密切关注这个问题:) 你不能简单地在命中测试中返回 nil 这就是为什么我添加了条件并调用 super.hitTest 但现在你说你的滚动视图覆盖了整个视图并且命中测试总是会成功删除我的答案

标签: ios uiviewcontroller uigesturerecognizer uitouch uiresponder


【解决方案1】:

感谢this very helpful WWDC video,我想我更了解这里发生了什么。

给定一个传入的触摸,系统首先将该触摸与最深的命中测试视图相关联;在我的情况下,这是 UIScrollView。然后它显然会回到超级视图的层次结构中,寻找任何其他附加的识别器。文档的这一关键位暗示了这种行为:

手势识别器对针对特定视图和所有该视图的子视图进行命中测试的触摸进行操作。

滚动视图有自己的内部平移识别器,它要么取消无法识别的触摸,要么可能退回到不会发生向前触摸响应链的响应器方法。这就解释了为什么我的响应器方法永远不会被调用,即使我自己的识别器被禁用。

有了这些信息,我可以想出一些可能的方法来解决我的问题,例如:

  • 如果/当关联视图位于子控制器下时,请使用手势委托方法忽略触摸。
  • 编写一个“null”手势识别器子类来捕获所有触摸并忽略它们,并将其附加到子控制器的根视图。

但我最终所做的只是重新排列我的视图层次结构,在顶部使用一个新的空视图,以便我的子控制器视图可以是主内容视图的兄弟,而不是它的子视图。

因此视图层次结构从此发生变化:

到这里:

这解决了我的问题:我的手势识别器不再与对子控制器视图进行命中测试的触摸进行交互。而且我认为它更好地捕捉了我的应用控制器之间的概念关系,而不需要任何额外的逻辑。

【讨论】:

  • 谢谢。我将视图重新排列为“顶部”视图的祖先,而祖先现在得到了未处理的手势。之前它只是祖先的孩子,没有得到未经处理的手势。
  • @4bar - 你应该得到一个高贵的答案!跳出框框思考的绝妙例子!
猜你喜欢
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多