UIView *view = [panGesture view]; if (panGesture.state == UIGestureRecognizerStateBegan) { self.collectionView.panGestureRecognizer.enabled = NO; self.offsetY = view.frame.origin.y; } else if (panGesture.state == UIGestureRecognizerStateBegan || panGesture.state == UIGestureRecognizerStateChanged) { CGPoint translation = [panGesture translationInView:[view superview]]; if (view.frame.origin.y <= 0 && translation.y < 0) { return; } [view setCenter:CGPointMake([view center].x, [view center].y + translation.y)]; [panGesture setTranslation:CGPointZero inView:view]; } else if (panGesture.state == UIGestureRecognizerStateEnded) { CGPoint velocity = [panGesture velocityInView:view]; UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] init]; UICollisionBehavior *collision = [[UICollisionBehavior alloc] init]; collision.collisionDelegate = self; [collision addItem:self.collectionView]; if (self.offsetY < view.frame.origin.y) { pushBehavior.pushDirection = CGVectorMake(0, 1.0); [collision addBoundaryWithIdentifier:@"max" fromPoint:CGPointMake(0, 2*self.view.frame.size.height + 1) toPoint:CGPointMake(self.view.frame.size.width, 2*self.view.frame.size.height + 1)]; } else { pushBehavior.pushDirection = CGVectorMake(0, -1.0); [collision addBoundaryWithIdentifier:@"min" fromPoint:CGPointMake(0, 0) toPoint:CGPointMake(self.view.frame.size.width, 0)]; } [pushBehavior addItem:self.collectionView]; pushBehavior.magnitude = fabs(velocity.y); [self.animator addBehavior:pushBehavior]; [self.animator addBehavior:collision]; [self.animator updateItemUsingCurrentState:self.collectionView]; self.collectionView.panGestureRecognizer.enabled = YES; }