Search code examples
iosuicollectionviewcatransform3d

UICollectionViewCell Perspective Transform on Appear/Disappear


My goal is to create a UICollectionView which, like the one in the image below, has cells that fade with perspective on exit and enter. My scrollViewDidScroll delegate function is as follows:

NSArray *rows = [self.feedCollectionView indexPathsForVisibleItems];
for (NSIndexPath *path in rows) {
    if (path.row != 1) {
        continue;
    }
    UICollectionViewCell *cell = [self.feedCollectionView cellForItemAtIndexPath:path];

    float height = cell.frame.size.height;
    float position = cell.frame.origin.y - scrollView.contentOffset.y;
    float offsetFromBottom = self.feedCollectionView.frame.size.height- position;
    float fraction = MAX(((height - offsetFromBottom)/height), 0);
    //float angleFormula = -((height - offsetFromBottom)/height)*M_PI/2;
    float rotation = MIN(-((height - offsetFromBottom)/height)*M_PI/2, 0);

    CGRect frame = cell.frame;
    [self setAnchorPoint:CGPointMake(0.5, 0.0) forView:cell];
    cell.frame = frame;

    CATransform3D transform = CATransform3DIdentity;
    transform.m34 = -1.0/(height * 4.6666667);
    transform = CATransform3DRotate(transform, rotation, 1, 0, 0);

    [cell.layer setAnchorPoint:CGPointMake(0.5, 0.0)];
    cell.layer.sublayerTransform = transform;

    float delta = asinf(fraction);

    [cell.layer setTransform:CATransform3DMakeRotation(delta, 1, 0, 0)];
}

Unfortunately, the setAnchorPoint moves the cells out of their natural place when they're loaded and the entire collectionView becomes chaotic. Not setting the anchor point to the new position, however, makes it impossible to get good perspective transformation, as it ensures the top edge of the cell does not widen.

The cells originally on the screen are fine until they disappear and reappear, at which point the frame has mysteriously changed. All cells not on the screen originally have the problem to begin with. It seems UICollectionView has a problem with me setting the anchorPoint property on its cells. Is there any way to modify the perspective transformation to act as though the anchorPoint is different, or a way to get the collectionview to accept that its cells may have a different anchor point?

desc


Solution

  • Answering my own question I guess.

    The solution was to perform the transforms and adjust the anchor point on the cell's contentView.