I want to use a swipe animation for a custom view that is on top of the view of my UIViewController. The user should be able to swipe up the custom view to the top to send it out of the screen. Exactly like the iOS7 App Switcher gesture to kill an app:
At the moment I use a UIPanGestureRecognizer, that is attached to my custom view. When the custom view's is dragged in the upper 100 pixels of the parent view, I start an UIAnimation to send the custom view out of the parent view:
- (IBAction)panWasRecognized:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded && _myView.center.y >= 100)
{
[self resetViewPosition];
}
else
{
CGPoint translation = [recognizer translationInView:_myView.superview];
CGPoint center = _myView.center;
center.x += translation.x;
center.y += translation.y;
_myView.center = center;
if (center.y < 100)
{
NSLog(@"swipe up gesture detected ...");
[self hideView];
}
[recognizer setTranslation:CGPointZero inView:_myView.superview];
}
}
This method is working, but not quite as well as the iOS7 app switcher. Is there a better way to do this?
EDIT:
So here is what works for me:
- (IBAction)panWasRecognized:(UIPanGestureRecognizer *)recognizer
{
CGPoint velocity = [recognizer velocityInView:recognizer.view];
if (recognizer.state == UIGestureRecognizerStateEnded && _myView.center.y >= 150)
{
[self resetViewPosition];
}
else
{
CGPoint translation = [recognizer translationInView:_myView.superview];
CGPoint center = _myView.center;
center.x += translation.x;
center.y += translation.y;
_myView.center = center;
if (recognizer.state == UIGestureRecognizerStateEnded && center.y < 150)
{
NSLog(@"swipe up gesture detected ...");
// speed
CGFloat xPoints = -170.0f;
CGFloat velocityX = [recognizer velocityInView:self.view].x;
NSTimeInterval duration = xPoints / velocityX;
[self hideViewWithDuration:duration];
}
}
[recognizer setTranslation:CGPointZero inView:_myView.superview];
}
- (void)hideViewWithDuration:(float)duration
{
NSLog(@"Animation duration: %f", duration);
[UIView animateWithDuration:duration
delay:0.0f
options: UIViewAnimationOptionCurveEaseOut
animations:^
{
CGRect frame = _myView.frame;
frame.origin.y = -170;
frame.origin.x = 10;
_myView.frame = frame;
}
completion:^(BOOL finished)
{
[_myView setHidden:YES];
CGRect frame = _myView.frame;
frame.origin.y = self.view.frame.size.height;
frame.origin.x = 10;
_myView.frame = frame;
[_myView setHidden:NO];
NSLog(@"View is hidden.");
_hideInProgress = NO;
}];
}
- (void)resetViewPosition
{
[UIView animateWithDuration:0.5
delay:0
options: UIViewAnimationOptionCurveEaseOut
animations:^
{
CGRect frame = _myView.frame;
frame.origin.y = (self.view.frame.size.height - _myView.frame.size.height) / 2;
frame.origin.x = 10;
_myView.frame = frame;
}
completion:^(BOOL finished)
{
NSLog(@"View is back to its original place.");
}];
}