UICollectionView:动画上选择单元格大小变化(UICollectionView: An

2019-06-21 18:51发布

我想要做的是改变一个UICollectionViewCell的大小,并以动画这种变化,被选中单元格时。 我已经设法通过标记细胞在选择做动画的collectionView: didSelectItemAtIndexPath:然后调用reloadData我UICollectionView,具有不同的尺寸显示选定的单元格。

然而,这种情况发生在所有的一次,我不知道如何让动画的大小变化。 有任何想法吗?

我已经找到动画uicollectionview细胞上的选择 ,但得到的答复是不特定的我,我也没弄明白但如果它也能帮助我在我的情况。

Answer 1:

[UIView transitionWithView:collectionView 
                  duration:.5 
                   options:UIViewAnimationOptionTransitionCurlUp 
                animations:^{

    //any animatable attribute here.
    cell.frame = CGRectMake(3, 14, 100, 100);

} completion:^(BOOL finished) {

    //whatever you want to do upon completion

}];

玩弄沿着你的内部类似的规定didselectItemAtIndexPath方法。



Answer 2:

大通罗伯茨的帮助下,我现在找到了解决我的问题。 我的代码基本上是这样的:

// Prepare for animation

[self.collectionView.collectionViewLayout invalidateLayout];
UICollectionViewCell *__weak cell = [self.collectionView cellForItemAtIndexPath:indexPath]; // Avoid retain cycles
void (^animateChangeWidth)() = ^()
{
    CGRect frame = cell.frame;
    frame.size = cell.intrinsicContentSize;
    cell.frame = frame;
};

// Animate

[UIView transitionWithView:cellToChangeSize duration:0.1f options: UIViewAnimationOptionCurveLinear animations:animateChangeWidth completion:nil];

对于进一步的解释:

  1. 其中最重要的一步是invalidateLayout上的呼叫UICollectionView.collectionViewLayout您使用。 如果你忘了,它很可能会发生细胞将在您的收藏边界增长 - 这就是你最有可能不希望发生的事情。 还要考虑你的代码应该在某些时候出示您的细胞的新的大小来布局。 在我的情况(我使用的是UICollectionViewFlowLayout ),我调整了collectionView:layout:sizeForItemAtIndexPath方法来反映修改单元格的新的大小。 忘记那一部分,什么都不会发生在你的单元尺寸在所有如果你首先调用invalidateLayout ,然后尝试在动画尺寸的变化。

  2. 最奇怪的(至少对我来说),但重要的是你叫invalidateLayout 不是动画块内。 如果这样做,动画将不会显示平滑,但出问题和闪烁。

  3. 你要调用UIView小号transitionWithView:duration:options:animations:completion:方法与细胞作为论据transitionWithView ,而不是整个集合视图,因为它是你想获得动画,而不是整个采集的细胞。

  4. 我用intrinsicContentSize我的手机回我要的大小的方法-在我的情况,我增长和收缩的单元格的宽度要么显示一个按钮或隐藏它,这取决于电池的选择状态。

我希望这将帮助一些人。 对于我来说,花了几个小时才能弄清楚如何正确地作出这样的动画作品,所以我尝试从耗时的负担,解放别人。



Answer 3:

动画单元的尺寸适用于收集意见以同样的方式,因为它确实为表视图。 如果你想动画单元的大小,有反映单元的状态(在我的情况,我只是用一个标志(CollectionViewCellExpanded,CollectionViewCellCollapsed),并相应返回CGSize的数据模型。

当你打电话的空performBathUpdates打电话,视图会自动动画。

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    [collectionView performBatchUpdates:^{
        // append your data model to return a larger size for
        // cell at this index path
    } completion:^(BOOL finished) {

    }];
}


Answer 4:

我已经使用过成功的动画改变-setCollectionViewLayout:animated:创建相同的集合视图布局的新实例。

例如,如果您使用的是UICollectionViewFlowLayout ,则:

// Make sure that your datasource/delegate are up-to-date first

// Then animate the layout changes
[collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES];


Answer 5:

这是我发现的最简单的办法 - 就像一个魅力。 流畅的动画效果,并且不弄乱布局。

迅速

    collectionView.performBatchUpdates({}){}

OBJ-C

    [collectionView performBatchUpdates:^{ } completion:^(BOOL finished) { }];

该块(斯威夫特闭包)应该被有意留空白!



Answer 6:

动画单元大小的一个好方法是重写isSelected在collectionViewCell本身。

class CollectionViewCell: UICollectionViewCell {

    override var isHighlighted: Bool {
        didSet {
            if isHighlighted {
                UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: {
                    self.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
                }, completion: nil)
            } else {
                UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: {
                    self.transform = CGAffineTransform(scaleX: 1, y: 1)
                }, completion: nil)
            }
        }
    }

}


Answer 7:

使用performBatchUpdates将无法运行动画的单元格内容的布局。 相反,你可以使用以下命令:

    collectionView.collectionViewLayout.invalidateLayout()

    UIView.animate(
        withDuration: 0.4,
        delay: 0.0,
        usingSpringWithDamping: 1.0,
        initialSpringVelocity: 0.0,
        options: UIViewAnimationOptions(),
        animations: {
            self.collectionView.layoutIfNeeded()
        },
        completion: nil
    )

这给出了一个非常流畅的动画效果。

这类似于伊格震颤的答案,但过渡动画并没有为我正常工作。

见https://github.com/cnoon/CollectionViewAnimations的完整解决方案。



Answer 8:

这为我工作。

    collectionView.performBatchUpdates({ () -> Void in
        let ctx = UICollectionViewFlowLayoutInvalidationContext()
        ctx.invalidateFlowLayoutDelegateMetrics = true
        self.collectionView!.collectionViewLayout.invalidateLayoutWithContext(ctx)
    }) { (_: Bool) -> Void in
    }


文章来源: UICollectionView: Animate cell size change on selection