我的主视图中有一个2维按钮数组,希望能够通过在此视图中拖动来移动它们。按钮很窄,大约23x23像素。我添加了控制事件touchDragExit
和touchDragOutside
的目标,但是在我将手指移到按钮之外后,它们被解雇了很多像素。因此,我使用在SO中找到的一些代码对UIButton
进行了子类化并覆盖了continueTrackingWithTouch
。注意我没有调用超类实现。
-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
CGFloat boundsExtension = 5.0f;
CGRect outerBounds = CGRectInset(self.bounds, -1 * boundsExtension, -1 * boundsExtension);
BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:self]);
if(touchOutside)
{
BOOL previousTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:self]);
if(previousTouchInside)
{
[self sendActionsForControlEvents:UIControlEventTouchDragExit];
}
else
{
[self sendActionsForControlEvents:UIControlEventTouchDragOutside];
}
}
return self.tracking;
}
两个事件都被正确触发,但我的UIControlEventTouchDragOutside
操作在调用其操作时收到错误的触摸信息。以下是我实施的第一部分:
-(void) dragOutside:(UIButton *) sender withEvents:(UIEvent *) event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint relativeLocToInitialCell = [touch locationInView:sender];
NSLog(@"Translation %f %f NumTouch %d",relativeLocToInitialCell.x, relativeLocToInitialCell.y, [[event allTouches] count]);
...
}
[[event allTouches] count]
仍然返回0,直到我的手指远离按钮。当然,relativeLocToInitialCell
字段x
和y
都是0,这是我用于以后计算的值。知道可能是什么问题吗?
UIPanGestureRecognizer
而不是touchdrag事件,但我无法使用它,因为它在处理一个事件之前触发得太快我得到另一个事件。
答案 0 :(得分:3)
我最终还要处理UIControlEventTouchDragInside
事件。虽然这看起来是一种解决方法,但考虑这些触摸拖动事件的基本原理使其成为一种合理的解决方案。所有拖动事件均来自touchesBegan, touchesMoved and touchesEnded
。 Apple在发送UIControlEventTouchDragOutside
之前添加了一些阈值,但直到发送阈值UIControlEventTouchDragInside
事件为止。
我的解决方案是删除重写的continueTrackingWithTouch
方法并继续其默认实现。然后我处理了内部和外部事件,并将我的初始化代码从exit事件移动到inside事件,并在inside事件中添加了控制语句。抽象代码如下所示:
-(void) dragInside:(UIButton *) sender withEvents:(UIEvent *) event
{
if(stillInsideOriginalControl) return;
UITouch *touch = [[event allTouches] anyObject];
CGPoint relativeLocToInitialCell = [touch locationInView:sender];
[self processTouch];
}
-(void) dragOutside:(UIButton *) sender withEvents:(UIEvent *) event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint relativeLocToInitialCell = [touch locationInView:sender];
[self processTouch];
}