我有一个点击手势识别器的视图。此视图的子视图是我的自定义类的一个实例,它继承自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!
}如果用户接触到UIControl内部,在X方向和Y方向拖动控件,然后离开屏幕,这个系统就能正常工作。在本例中,所有这三个函数都被调用,并且发生了“重要的事情”。
但是,如果用户接触到UIControl,只在X方向拖动控件,然后解除屏幕,我们就有问题了。前两个函数被调用,但是当接触点离开屏幕时,会调用点击手势识别器,而不调用endTrackingWithTouch。
如何确保endTrackingWithTouch总是被调用?
发布于 2014-09-24 14:08:58
我以一种我认为是黑客的方式修正了这个问题,但是考虑到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()
}在superview的课堂上:
pauseGestureRecognizer()
{
tapGestureRecognizer.enabled = false
}
resumeGestureRecognizer()
{
tapGestureRecognizer.enabled = true
}这是因为我没有处理多点触摸(在跟踪UIControl的触摸时,我可以不接收点击触摸事件)。
理想情况下,控件不应该告诉视图暂停手势识别器-手势识别器不应该干预控件的触摸开始!但是,即使将手势识别器的cancelsTouchesInView设置为false也不能阻止这一点。
发布于 2017-03-26 00:05:04
有一种方法可以很好地自我包含:实例化您自己的TapGestureRecognizer并将它附加到您的自定义控件中,例如在Objective中,
_tapTest = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
_tapTest.numberOfTapsRequired = 1;
[self addGestureRecognizer:_tapTest];然后实现tapped操作处理程序来处理tap:
- (void)tapped:(UITapGestureRecognizer *)recognizer {...}在我的例子中,我处理tapped和endTrackingWithTouch:withEvent:一样;您的里程可能不同。
这样,在任何superview能够抓取它之前,您就可以得到水龙头,而不必担心控件后面的视图层次结构。
发布于 2014-09-19 18:10:16
当UIControl在跟踪时被移动时,它可能会取消它的跟踪。尝试重写cancelTrackingWithEvent,看看是否是这样。如果确实看到了“取消”,则必须在此控件的父层次结构中的某个不移动视图中跟踪您的触摸。
https://stackoverflow.com/questions/25939178
复制相似问题