未调用UIControl endTrackingWithTouch

use*_*430 6 uicontrol ios

我有一个带有轻敲手势识别器的视图.此视图的子视图是我的自定义类的实例,它继承自UIControl.我遇到一个问题,UIControl子类有时会允许触摸事件传递到父视图,而不应该.

在UIControl子类中,我重写了这些函数(代码在Swift中)

override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) -> Bool
{
    return true
}

override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) -> Bool
{
    // The code here moves this UIControl so its center is at the touchpoint
    return true
}

override func endTrackingWithTouch(touch: UITouch,withEvent event: UIEvent)
{
    // Something important happens here!
}
Run Code Online (Sandbox Code Playgroud)

如果用户在UIControl内触地,在拖动控制解决此系统工作得很好,两个 X和Y方向,然后升空的画面.在这种情况下,调用所有这三个函数,并发生"重要的事情".

但是,如果用户使用UIControl触摸,在X方向上拖动控件,然后从屏幕上抬起,我们就会遇到问题.调用前两个函数,但是当触点从屏幕上抬起时,调用轻击手势识别器,并且不调用endTrackingWithTouch.

如何确保始终调用endTrackingWithTouch?

use*_*430 5

我用一种我认为是黑客的方式修复了这个问题,但考虑到 UIGestureRecognizer 的工作原理,确实没有其他选择。

发生的情况是点击手势识别器正在取消控件的跟踪并注册点击手势。这是因为当我水平拖动时,我恰好拖动了很短的距离,这被解释为点击手势。

当 UIControl 正在跟踪时,必须禁用点击手势识别器:

override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) -> Bool
{
    pointerToSuperview.pauseGestureRecognizer()
    return true
}

override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) -> Bool
{
    // The code here moves this UIControl so its center is at the touchpoint
    return true
}

override func endTrackingWithTouch(touch: UITouch,withEvent event: UIEvent)
{
    // Something important happens here!
    pointerToSuperview.resumeGestureRecognizer()
}

override func cancelTrackingWithEvent(event: UIEvent?)
{
    pointerToSuperview.resumeGestureRecognizer()
}
Run Code Online (Sandbox Code Playgroud)

在超级视图的类中:

pauseGestureRecognizer()
{
    tapGestureRecognizer.enabled = false
}

resumeGestureRecognizer()
{
    tapGestureRecognizer.enabled = true
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为我不处理多点触控(在使用 UIControl 跟踪触摸时不接收点击触摸事件对我来说是可以的)。

理想情况下,控件不必告诉视图暂停手势识别器 - 手势识别器一开始就不应该干扰控件的触摸!然而,即使将手势识别器的 cancelsTouchesInView 设置为 false 也无法阻止这种情况。