why is there a delay when moving object using UIPanGestureRecognizer

喜夏-厌秋 提交于 2019-12-03 12:19:27

问题


I'm moving UIView object using UIPanGestureRecognizer - how much I drag my finger on screen, that much I move the view in the same direction (only in X - left or right, Y is not changing). It works fine, but with (very noticeable) delay.

Here is the method that handles the UIPanGestureRecognizer event:

-(void)movePages:(UIPanGestureRecognizer *)sender
{
    if(switchingMode == 1){
        if([sender state] == UIGestureRecognizerStateBegan){
            fingerStartPosition = [sender locationInView:self.view].x;
            viewStartPosition = [[viewControllers objectAtIndex:activeViewControllerIndex] view].center;
        }
        [[[[viewControllers objectAtIndex:activeViewControllerIndex] view] layer] setPosition:CGPointMake(viewStartPosition.x - (fingerStartPosition - [sender locationInView:self.view].x) , viewStartPosition.y)];

    }
}

I've tried to set position of the view using its layer, I've also tried setting the frame, using animations with different durations, but everything behaved the same. Any idea why this delay occurs ?


回答1:


Use a UILongPressGestureRecognizer and set the minimumPressDuration to 0.0. This recognizes instantly and you get all the same updates including the UIGestureRecognizerStateChanged with the updated location.




回答2:


I found that it was faster responding if you use just regular touchesBegan, Moved and Ended. I even subclassed a UIGestureRecognizer, and it still had lag on the panning gesture. Even though the touchesBegan within the UIGestureRecognizer would trigger on time, the state change would take a half second to change its state... It seems faster to just use a plain old TouchesBegan, especially if you're cpu is doing a lot.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    if touches.count == 1
    {
        initialTouchLocation = (touches.first?.locationInView(self).x)!
    }
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    if touches.count == 1
    {
        let locationInView = touches.first?.locationInView(self)
        if !thresholdHit
        {
            //this is the threshold for x movement in order to trigger the panning...
            if abs(initialTouchLocation - locationInView!.x) > 1
            {
                thresholdHit = true
            }
        }
        else
        {
            if (self.frame.width != CGFloat(screenSize))
            {
                let panDelta = initialTouchLocation - locationInView!.x
            }
        }
    }
}



回答3:


The GestureRecognizer can't be sure, if it is a pan gesture, before you moved your finger some pixels. I don't know the exact tolerance value, but that is why you feel a delay.

Documentation:

A panning gesture is continuous. It begins when the minimum number of fingers allowed have moved enough to be considered a pan.

If you want instant movement, you probably need to build your own logic using touchesMoved:.

Another approach could be, to animate to the first recognized point. But that doesn't remove the delay. For that approach you could have a look at my JDDroppableView on github.



来源:https://stackoverflow.com/questions/10728066/why-is-there-a-delay-when-moving-object-using-uipangesturerecognizer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!