UICollectionVIew:在滚动时为单元格添加动画

我希望在用户滚动列表时使用UICollectionView项目进行动画显示(我使用的是UICollectionViewFlowLayout的子类)。

我在布局管理器中指定位置,我希望能够做的是也指定一个初始变换,并在正确的时间(当单元格第一次出现在屏幕上时)在动画中应用。 要查看我的意思,请查看iOS上的Google Plus应用。 理想情况下,根据细胞的位置不同的变换。

我似乎无法找到一种方法来查明何时显示一个单元格(没有与UITableView上的willDisplayCell等效)或任何指向该目标的指针。

有什么建议么?

您可以在此屏幕截图中制作Google Plus中的动画: Google Plus应用程序中的示例

另外,请看一下iPad上的iPhoto。 我不知道他们是否使用UIcollectionView(可能不是,因为它在iOS5上工作),但这是如果我正在寻找的效果,照片似乎从右侧飞入。


您可以独立于自定义布局来实现此效果。

动画代码应该放在collectionView:cellForItemAtIndexPath:

当一个单元格出队时,其frame将被设置为布局中指定的内容。 您可以将其存储在临时变量中作为单元格的最终frame 。 然后,您可以将cell.frame设置为屏幕外的初始位置,然后向期望的最终位置设置动画。 沿着以下方向的东西:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

    CGRect finalCellFrame = cell.frame;
    //check the scrolling direction to verify from which side of the screen the cell should come.
    CGPoint translation = [collectionView.panGestureRecognizer translationInView:collectionView.superview];
    if (translation.x > 0) {
        cell.frame = CGRectMake(finalCellFrame.origin.x - 1000, - 500.0f, 0, 0);
    } else {
        cell.frame = CGRectMake(finalCellFrame.origin.x + 1000, - 500.0f, 0, 0);
    }

    [UIView animateWithDuration:0.5f animations:^(void){
        cell.frame = finalCellFrame;
    }];

    return cell;
}

上面的代码将根据滚动方向为水平UICollectionView上的单元格生成动画,这些单元格来自屏幕的顶部,以及来自任何一侧。 您还可以检查当前的indexPath ,让单元格从更复杂的布局上的不同位置进行动画制作,以及将其他属性与框架一起动画或应用变形。


您需要在集合视图布局中重写initialLayoutAttributesForAppearingItemAtIndexPath: 在这里,您可以设置布局属性项目(包括变换)上的任何属性,该属性将在单元格出现后被动画为实际属性。

如果标准布局属性对象没有给您足够的选项,您可以对它进行子类化,添加额外的属性,并覆盖您的单元格上的applyLayoutAttributes:拾取额外的属性。

这只在将单元格添加到集合视图时才起作用。

要在向下滚动集合视图时将变换应用于单元格,我会考虑将它们直接应用于单元格(在cellForItem )或布局属性(可能是名为initialTransform的属性)。 将布局属性应用于单元格时,您需要检查initialTransform ,应用它,然后将其设置为标识,然后触发动画以进行标识转换,因此仅当单元格第一次滚动到屏幕。 我没有执行过这样的事情,只是猜测我该怎么做。


正如马克在评论中提到的那样,他最终使用了滚动视图,我想展示如何使用标准表视图进行操作。 它与google +中看到的效果不一样,但可以很容易地进行修改。

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    static CGFloat duration = .5;
    static NSUInteger xOffset = 50;
    static NSUInteger yOffset = 200;
    if(scrollDirection == STAScrollDirectionDown && lastAnimatedIndex < indexPath.row)
    {
        cell.frame = CGRectMake(cell.frame.origin.x - xOffset, cell.frame.origin.y+yOffset, cell.frame.size.width, cell.frame.size.height);
        [UIView animateWithDuration:duration
                         animations:^{
            cell.frame = CGRectMake(cell.frame.origin.x + xOffset, cell.frame.origin.y - yOffset, cell.frame.size.width, cell.frame.size.height);
        } completion:^(BOOL finished) {
            lastAnimatedIndex = indexPath.row;
        }];
    }
}

就在显​​示单元格之前,我们为每个单元格分配一个偏移量(可能还有一个旋转),然后再将其设置回原来的设置。


一个更激动人心的例子:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    CATransform3D rotation = CATransform3DMakeRotation( (90.0*M_PI)/180, .0, 0.5, 0.5);
    cell.contentView.alpha = 0.8;
    cell.contentView.layer.transform = rotation;
    cell.contentView.layer.anchorPoint = CGPointMake(0, 0.5);

    [UIView animateWithDuration:.5
                     animations:^{
                         cell.contentView.layer.transform = CATransform3DIdentity;
                         cell.contentView.alpha = 1;
                         cell.contentView.layer.shadowOffset = CGSizeMake(0, 0);
                     } completion:^(BOOL finished) {
                     }];
}
链接地址: http://www.djcxy.com/p/84161.html

上一篇: UICollectionVIew: Animate cells as they scroll in

下一篇: Advanced UICollectionView animation using invalidateLayout calls