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