Question

I have a UIPanGesture View in my app. I have a button on the very bottom of my app and when the user slides it up it goes to the very top of the screen. THe problem is when when the user slides it up, it stops in the center, then the user has to slide it up again for it to go to the very top of the screen. How do I make it so one swipe up and its at the very top? Also, Flicking it down it also stops in the center but it will not go to the starting point which is at the very bottom of the screen once it is flicked up. The lowest it will go is the middle of the screen. Here is my code.

 -(IBAction) dragMe: (UIPanGestureRecognizer *)recognizer {

CGPoint translation = [recognizer translationInView:recognizer.view.superview];

recognizer.view.center = CGPointMake(recognizer.view.center.x, +  recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:recognizer.view.superview];

if (recognizer.state == UIGestureRecognizerStateEnded) {

    CGPoint velocity = [recognizer velocityInView:recognizer.view.superview];
    CGFloat magnitude = sqrtf((velocity.y * velocity.y));
    CGFloat slideMult = magnitude / 50
    ;
    NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);

    float slideFactor = 0.1 * slideMult; // Increase for more of a slide
    CGPoint finalPoint = CGPointMake(recognizer.view.center.x,
                                     recognizer.view.center.y + (velocity.y * slideFactor));
    finalPoint.x = MIN(MAX(finalPoint.x, 160), recognizer.view.superview.bounds.size.width);
    finalPoint.y = MIN(MAX(finalPoint.y, 284), recognizer.view.superview.bounds.size.height);

    [UIView animateWithDuration:slideFactor*.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        recognizer.view.center = finalPoint;
    } completion:nil];



}

}

Thanks in Advance!

Was it helpful?

Solution

You have to understand what's the code in your function really does, in order to be able to see where the problem is.

This code inside the if (recognizer.state == UIGestureRecognizerStateEnded) it's calculating the final point that your draggable view will be, according to the velocity of the gesture, and animating it to this point.

This code here

finalPoint.x = MIN(MAX(finalPoint.x, 160), recognizer.view.superview.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 284), recognizer.view.superview.bounds.size.height);

it's treating the bounds of your super view, in order to don't allow your draggable view to pass it's parent's bounds.

For some reason, the minimum values for the x and y value of the final point in your code are 160 and 284, and that will be like almost in the center of your super view.

To correct this, change this code to:

finalPoint.x = MIN(MAX(finalPoint.x, recognizer.view.bounds.size.width/2.0), recognizer.view.superview.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, recognizer.view.bounds.size.height/2.0), recognizer.view.superview.bounds.size.height);

Now the origin of your draggable view will not pass the 0's values of it's parents bounds.

It's important that you understant that's your code it's NOT animating your button (draggable view) to the top of your view, but just, like I said before, calculating it's final position according to the velocity.

If what you really want it's the button to toggle between the top and the bottom of the view, try something like this:

//in .h file    
@interface yourClass : yourFatherClass 
{ 
    BOOL _isInTop; 
}

//in the gesture method
if (_isInTop){ 
   _isInTop = NO; 
   finalPoint.y = recognizer.view.superview.bounds.size.height - recognizer.view.bounds.size.height/2.0 
} 
else 
{ 
   _isInTop = YES; 
   finalpoint.y = recognizer.view.bounds.size.height/2.0 
}

Please give some feedback if that's really what you were looking for

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top