Skip to content

Instantly share code, notes, and snippets.

@cbess
Last active August 29, 2015 13:56
Show Gist options
  • Select an option

  • Save cbess/8969659 to your computer and use it in GitHub Desktop.

Select an option

Save cbess/8969659 to your computer and use it in GitHub Desktop.
Split UICollectionViewCell (or any view) into two pieces, then send (animation off screen) in opposite directions.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
// we are placing it above the collection view, in the VC.view,
// so convert the rect to that coord. region
CGRect cellRect = [collectionView convertRect:cell.frame toView:self.view];
CGRect cellBounds = cell.bounds;
// get an image of the cell
UIGraphicsBeginImageContextWithOptions(cellRect.size, YES, 1);
[cell.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *cellImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// chop the image up
CGSize portionSize = CGSizeMake(CGRectGetWidth(cellRect), CGRectGetMidY(cellBounds));
CGImageRef topImageRef = CGImageCreateWithImageInRect(cellImage.CGImage, (CGRect){CGPointZero, portionSize});
CGImageRef bottomImageRef = CGImageCreateWithImageInRect(cellImage.CGImage, (CGRect){{0, CGRectGetMidY(cellBounds)}, portionSize});
// move portions apart
CALayer *topLayer = [CALayer layer];
topLayer.contents = (__bridge id)topImageRef;
topLayer.frame = (CGRect){cellRect.origin, portionSize};
CALayer *bottomLayer = [CALayer layer];
bottomLayer.contents = (__bridge id)bottomImageRef;
bottomLayer.frame = (CGRect){{CGRectGetMinX(cellRect), CGRectGetMinY(cellRect) + CGRectGetMidY(cellBounds)}, portionSize};
[self.view.layer addSublayer:topLayer];
[self.view.layer addSublayer:bottomLayer];
cell.hidden = YES;
// move the layers off screen
CABasicAnimation *upAnimation = [CABasicAnimation animation];
// no fromValue needed, current position of layer is used, when not provided
upAnimation.toValue = @(-CGRectGetHeight(topLayer.bounds));
upAnimation.removedOnCompletion = NO;
upAnimation.fillMode = kCAFillModeForwards;
upAnimation.duration = .9f;
upAnimation.timingFunction = [CAMediaTimingFunction functionWithName:@"easeIn"];
[topLayer addAnimation:upAnimation forKey:@"position.y"];
CABasicAnimation *downAnimation = [CABasicAnimation animation];
downAnimation.toValue = @(CGRectGetHeight(self.view.bounds) + CGRectGetMidY(bottomLayer.bounds));
downAnimation.removedOnCompletion = NO;
downAnimation.fillMode = kCAFillModeForwards;
downAnimation.duration = upAnimation.duration;
downAnimation.timingFunction = upAnimation.timingFunction;
[bottomLayer addAnimation:downAnimation forKey:@"position.y"];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment