TheObjCGuy
TheObjCGuy

Reputation: 687

simulate an elastic animation with UIPangestureRecognizer

I'm trying to use UIPangestureRecognizer for simulate an "elastic" effect. I would like drag an UIView around but it should appears anchored in a specific point of his superview.

I tried with this code, decreasing the offeset with a multiplier, but it is linear and the effect is not what i'm looking for.

float percentage = distance / maxDistance;
float multiplier = (1 - percentage) ;
CGPoint center = { self.targetView.center.x , self.targetView.center.y +  translation.y * multiplier};  
[self.targetView setCenter:center];
[recognizer setTranslation:CGPointZero inView:self.view];

I found this repository https://github.com/warrenm/AHEasing, but i don't understand how can i use the ExponentialEaseOut.

Upvotes: 4

Views: 1115

Answers (2)

Dinkman123
Dinkman123

Reputation: 476

I actually found a really simple solution to this. Not sure why you'd need a third-party library here, and in general I tend to avoid incorporating them if I don't need to.

Your friend here is the hyperbolic tangent (tanh) function. It crosses the x axis at 45 degrees and then hits an asymptote at 1 just after the input value of 2.

I used this to implement horizontal swiping to reveal date/time (similar to how it's done in iOS7 Messages). Use this code in handlePan:

frameOffset = -OFFSET_MAX * tanh(translation.x / INPUT_SENSITIVITY);

Play with the OFFSET_MAX and INPUT_SENSITIVITY to tune it for your purposes. I use 80.0f for OFFSET_MAX (maximum distance I want the swipe to move the view) and 150.0f for INPUT_SENSITIVITY.

...

As for the end-pan animation, you can use the options field of UIView animateWithDuration to set the right animation curve. For the duration, you can either use a fixed duration (e.g., 0.15 seconds) or scale that value based on the total offset pre-return. Given that people expect a faster "snap back" for a larger offset, I've found that using a fixed duration will look pretty good generally.

Upvotes: 9

TheObjCGuy
TheObjCGuy

Reputation: 687

After an entire afternoon (i'm not so good in math) i found a solution for this problem.

I've normalized the distance between the view and my anchor point and used a basic function to bring this value to zero in a non-linear way. This is the function that i've used.

ease out function

When the user raise the finger, I bring back the view using the Facebook pop framework, to simulate a fancy spring animation.

enter image description here

Upvotes: 2

Related Questions