在Swift中阻止触摸事件传递到后面的视图

3
我有一个scrollview和一个子视图,如果用户在该子视图中进行某种触摸操作,则我想阻止scrollview移动,以便让用户在子视图中完成操作而不会受到scrollview的干扰。如果未检测到特定的触摸操作,则scrollview应该正常移动。
我使用原始触摸事件touchesBegan、touchesMoved来截取这些手势。我不使用gestureRecognizers,因为我想要识别的手势非常具体,我感觉使用没有抽象层更加舒适。
我知道通过查看stackoverflow上的很多答案,我可以仅持有一个对滚动视图的引用并在检测到手势时停止其移动。但我正在寻找一种更稳定的解决方案。我希望如果检测到手势,则停止向后传播事件(到任何视图),而无需持有任何这些后面视图的引用。
据我所知,在iOS中,视图是UIResponder的子类。当UIKit在屏幕上检测到触摸事件时,它将事件发送给第一个响应者,通常是最上面的子视图。我的问题是:在touchesBegan中如何告诉UIKit:“不要将事件发送给响应链中的任何其他后续视图”。如果我能看到scrollview在后面移动,那么UIKit必须已将事件转发给它(尽管我在touchesBegan中没有调用super)。
例如,在Android中,View类的onTouchEvent函数返回一个布尔值。false告诉android继续传播事件,true告诉其停止传播。我正在寻找iOS中相同的机制:
@Override
public boolean onTouchEvent(MotionEvent e)
{
    return true ; // stops propagation 
}

在JavaScript(jQuery)中,有相似的机制:
$('#myview').bind('click', function(e) {
    e.stopPropagation() 
})

如何用Swift实现这个功能?


这个设置为false怎么样? - Sweeper
这是 UIScrollView 的一个属性。我正在寻找比持有要关闭的视图的引用更稳定的解决方案。明确地说:我希望 UIScrollView 即使在检测到触摸事件后,也不会意识到它(并且不会取消移动)。 - Jerem Lachkar
我没有尝试过这个,但是你可以尝试重写自定义视图的next属性,该属性应返回下一个响应者,以便在检测到手势时返回nil - Sweeper
尝试在我的子视图中使用override var next:UIResponder? { get { return nil }},但是滚动视图仍然在后面移动 :/ - Jerem Lachkar
找到了解决方案(在我的答案中发布):) - Jerem Lachkar
1个回答

4

找到了解决方案。这个问题比较棘手,所以如果有人遇到同样的问题,我会尝试让它更容易理解:

正如另一个SO答案所述,“原始触摸系统”(touchesBegantouchesMoved等)和“手势识别器系统”是互斥的,它们都位于“原始”的视图级别,并且是独立的。

这意味着当您拥有一个视图并触摸它时,您有可能将触摸处理功能委托给手势识别器系统,而不是原始触摸系统。通过 override var next:UIResponder? { get { return nil }} 覆盖 UIResponder 属性只强制 UIKit 不将事件转发“在原始触摸系统中”,而背后的视图的手势识别仍然会触发,因为它是完全独立的系统。

在我的情况下,我尝试使用 override var next:UIResponder? { get { return nil }} :后面的视图的 touchesBegan 在预期中保持安静,但我仍然可以在那里识别手势。

因此,UIScrollView 使用手势识别器来处理用户触摸。解决方案是关闭从您的最顶层视图开始的手势识别器系统,以便手势不会被转发:可以使用以下代码实现:

override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool 
{
    return !yourConditionToShutDownGR
}

我感到困惑,因为Android手势“检测器”系统是建立在原始触摸系统之上的。当你在public boolean onTouchEvent(MotionEvent event)中捕获触摸事件时,你可以将其作为手势检测器的参数传递,手势检测器会返回是否发现手势。这与iOS不同,在iOS中,手势识别器系统是在原始触摸系统旁边构建的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接