Was wondering how I would go about flicking or flinging a UIView, such as http://www.cardflick.co/ or https://squareup.com/cardcase demo videos.
I know how to drag items, but how do you give them gravity/inertia. Is this handled by IOS?
Was wondering how I would go about flicking or flinging a UIView, such as http://www.cardflick.co/ or https://squareup.com/cardcase demo videos.
I know how to drag items, but how do you give them gravity/inertia. Is this handled by IOS?
The kind of effects that you are describing as simulating a king of gravity/inertia can be produced by means of ease-out (start fast, end slow) and ease-in (start slow, end fast) timing functions.
Support for easing out and easing in is available in iOS, so I don't think you need any external library nor hard work (although, as you can imagine, your effect will need a lot of fine tuning).
This will animate the translation of an object to a given position with an ease-out effect:
[UIView animateWithDuration:2.0 delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^ {
self.image.center = finalPosition;
}
completion:NULL];
}
If you handle your gesture through a UIPanGestureRecognizer
, the gesture recognizer will provide you with two important information to calculate the final position: velocity
and translation
, which represent respectively how fast and how much the object was moved.
You can install a pan gesture recognizer in your view (this would be the object you would like to animate, I guess) like this:
UIPanGestureRecognizer* panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
[yourView addGestureRecognizer:panGestureRecognizer];
[panGestureRecognizer release];
And then handle the animation in your handler:
- (void)handlePanFrom:(UIPanGestureRecognizer*)recognizer {
CGPoint translation = [recognizer translationInView:recognizer.view];
CGPoint velocity = [recognizer velocityInView:recognizer.view];
if (recognizer.state == UIGestureRecognizerStateBegan) {
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
<track the movement>
} else if (recognizer.state == UIGestureRecognizerStateEnded) {
<animate to final position>
}
}
iOS doesn't have any built-in API for gravity/inertia. Your best options are:
Simulate the effect with animations: if you are flicking an object toward a target (it doesn't need to bounce off things), you could probably get a pretty good result just by sending it to the target and tweaking the animation timing curve.
Use a physics library. Chipmunk is a high quality one and there is a lot of iOS support available. You set up objects, assign them weights, describe their shapes, and then the library code will give you updated (x,y) coordinates so you can update your objects on screen.
There's nothing built into iOS that does this for you, but you could easily implement it yourself. I'd start by creating a gesture recognizer that recognizes the "flick" gesture that you want to use, possibly something that looks for constant direction and increase in velocity. When you recognize such a gesture, you just have to animate the affected view's position appropriately.