Well, I'm not a pro but, checking multiple answers, I managed to make my own code with which I am happy.
Please tell me how to improve it and if there are any bad practices I used.
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translatedPoint = [recognizer translationInView:self.postViewContainer];
CGPoint velocity = [recognizer velocityInView:recognizer.view];
float bottomMargin = self.view.frame.size.height - containerViewHeight;
float topMargin = self.view.frame.size.height - scrollViewHeight;
if ([recognizer state] == UIGestureRecognizerStateChanged) {
newYOrigin = self.postViewContainer.frame.origin.y + translatedPoint.y;
if (newYOrigin <= bottomMargin && newYOrigin >= topMargin) {
self.postViewContainer.center = CGPointMake(self.postViewContainer.center.x, self.postViewContainer.center.y + translatedPoint.y);
}
[recognizer setTranslation:CGPointMake(0, 0) inView:self.postViewContainer];
}
if ([recognizer state] == UIGestureRecognizerStateEnded) {
__block float newYAnimatedOrigin = self.postViewContainer.frame.origin.y + (velocity.y / 2.5);
if (newYAnimatedOrigin <= bottomMargin && newYAnimatedOrigin >= topMargin) {
[UIView animateWithDuration:1.2 delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^ {
self.postViewContainer.center = CGPointMake(self.postViewContainer.center.x, self.postViewContainer.center.y + (velocity.y / 2.5));
}
completion:^(BOOL finished) {
[self.postViewContainer setFrame:CGRectMake(0, newYAnimatedOrigin, self.view.frame.size.width, self.view.frame.size.height - newYAnimatedOrigin)];
}
];
}
else {
[UIView animateWithDuration:0.6 delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^ {
if (newYAnimatedOrigin > bottomMargin) {
self.postViewContainer.center = CGPointMake(self.postViewContainer.center.x, bottomMargin + self.postViewContainer.frame.size.height / 2);
}
if (newYAnimatedOrigin < topMargin) {
self.postViewContainer.center = CGPointMake(self.postViewContainer.center.x, topMargin + self.postViewContainer.frame.size.height / 2);
}
}
completion:^(BOOL finished) {
if (newYAnimatedOrigin > bottomMargin)
[self.postViewContainer setFrame:CGRectMake(0, bottomMargin, self.view.frame.size.width, scrollViewHeight)];
if (newYAnimatedOrigin < topMargin)
[self.postViewContainer setFrame:CGRectMake(0, topMargin, self.view.frame.size.width, scrollViewHeight)];
}
];
}
}
}
I have used two different animation, one is the default inertia one and the other if for when the user flings the containerView with high velocity.
It works well under iOS 7.