Drag a UIView part-way, then it moves on its own

2019-03-30 23:49发布

问题:

I have an app with a draggable UIView placed at the bottom. The draggable view isnt totally offscreen and it has a "pull tab" that the user can drag upwards or downwards. Dragging up and down currently works, but I would like to give it the same behavior as the Apple notifications slide out drawer.

For example, if I drag the view out 50% upwards and remove my finger from the screen, then I'd like the draggable view to continue to move upwards on its own. Likewise, if the user only dragged the view out, say 30% upwards, then the view should drop back down to its default position.

Ideally, while I can do the dragging up/down, the motion isnt very "organic"....

Right now, I'm accomplishing the dragging upwards and downwards via UIPanGestureRecognizer, just in case that's relevant to the question.

Is it perhaps something along the lines of some clever math with the Y position of the draggable view, then doing the rest of the moving with some CAAnimations?

It might be a bit hard to visualize, so I've added some screens below.

Default screen with the a view at the bottom

The view dragged up via the tab on the right

Thank you!

回答1:

When your UIPanGestureRecognizer's state becomes UIGestureRecognizerStateEnded, use the velocityInView: message to find the velocity of the gesture.

If the velocity is close to zero, open or close the view based on the position of the view and the previous state of the view. For example, if the view was closed and it has been pulled out more than 10%, open it. If it was open and has been pulled in more than 10%, close it. Otherwise, move it back to its pre-gesture position.

If the velocity is not close to zero, use the sign of the Y component to determine the new state of the view. If the sign is positive, close the view. If the sign is negative, open the view.

You will have to experiment to figure out exactly what definition of “close to zero” feels best.

In any case, you will want to animate the view to its final position after the gesture ends, using a short duration (probably between .1 and .25 seconds). You may want to choose the duration based on the velocity and the distance the view needs to travel. The system notifications panel does this. (Try dragging it partway down slowly vs. rapidly. It animates to its final position at different speeds depending on how fast you were dragging it when you let go.)

You will want to experiment to find the best animation curve (UIViewAnimationOptionCurveEaseOut, etc.), and you may want to use a different curve depending on whether you're opening or closing the view and the velocity of the gesture.