使用后将覆盖 UIView 的触摸事件转发到下面的 UIScrollView

Posted

技术标签:

【中文标题】使用后将覆盖 UIView 的触摸事件转发到下面的 UIScrollView【英文标题】:Forward touch events from overlay UIView to UIScrollView below after using them 【发布时间】:2017-04-22 12:18:04 【问题描述】:

我有一个关于 ios / Swift 中的触摸处理的问题:

我的项目是这样的

UIViewController
     → UIView
          → OverlayView (UIView)
          → ScrollView (UIScrollView)

OverlayView 位于 UIScrollView 之上。两者都是 UIViewControllers 视图的子视图。

我这样做的原因是,我希望滚动视图能够正常运行(平移、缩放),而覆盖视图不受滚动视图可见内容更改的影响。此外,覆盖视图应处理触摸事件,以在下面的滚动视图中显示内容指南。

我现在面临的问题是,覆盖视图上的触摸事件(touchesBegantouchesMovedtouchesEndedtouchesCancelled)没有进入滚动视图(滚动视图没有平移/缩放)。

通过覆盖point(inside point: CGPoint, with event: UIEvent?) -> Bool 并返回false,我找到了将触摸事件转发到下一个视图的解决方案。但是覆盖视图上的触摸事件不会被调用。

有人知道如何实现这种行为吗?我尝试在覆盖视图中调用下一个响应者的所有触摸事件,但这也不起作用。

感谢您的帮助!

【问题讨论】:

不要在滚动视图上使用概览,而是创建 UIScrollview 的子类并在那里处理触摸。 您找到解决方案了吗? 【参考方案1】:

我认为您与point(inside point: CGPoint, with event: UIEvent?) -> Bool 走在正确的轨道上。

在您的“叠加”视图中,检查该点是否在子视图内。如果是,则返回 true 以允许与子视图交互。如果不是,则返回 false 以“将触摸传递”到底层滚动视图。

class PassThruOverlayView: UIView 

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool 

        for v in subviews 

            let ptInSub = v.convert(point, from: v.superview)
            if v.bounds.contains(ptInSub) 
                return true
            

        

        return false

    


您可以在此处查看一个工作示例(同时显示“Overlapping ScrollViews”和“ScrollView 上的 UIView Overlay):https://github.com/DonMag/ScrollViewPassThru

【讨论】:

感谢您的回答!问题是,我需要覆盖视图和滚动视图中的触摸事件:-/ hmmm...所以,您想要 - 例如 - 在覆盖视图中点击一个按钮并让它触发一个动作有同样的点击会触发底层滚动视图中的某些内容? 没错!这样做的目的是,我在滚动视图中有某种绘图画布,并希望在覆盖视图中插入用于精确绘图的指南。我这样做的原因是,我希望指南不随滚动视图的内容一起缩放。 你能举个例子来说明你正在尝试做什么吗?例如,您是否在覆盖视图上有一个UISlider,并且当您来回拖动滑块时,您希望在“画布”上绘制一条线?我认为您希望触摸在覆盖层的一部分上注册让它在画布上注册,但不能同时注册。【参考方案2】:

最好的办法是查找 hitTest (docs) - 在子类(覆盖)中创建逻辑,决定何时将触摸事件传递到下面的视图

【讨论】:

以上是关于使用后将覆盖 UIView 的触摸事件转发到下面的 UIScrollView的主要内容,如果未能解决你的问题,请参考以下文章

当很清楚并且不同的uiview可以处理它们时,如何忽略最上面的uiview中的触摸事件

UIView 事件转发无限循环

被覆盖的 UIControl 或 UIView 如何知道在其上方结束的触摸事件?

iOS:如何将触摸事件从子视图转发到超级视图? [复制]

仅将触摸事件转发到被触摸的视图

如何创建一个覆盖层来阻止触摸事件到它下面的 UI?