我想要做的是改变一个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];
对于进一步的解释:
其中最重要的一步是invalidateLayout
上的呼叫UICollectionView.collectionViewLayout
您使用。 如果你忘了,它很可能会发生细胞将在您的收藏边界增长 - 这就是你最有可能不希望发生的事情。 还要考虑你的代码应该在某些时候出示您的细胞的新的大小来布局。 在我的情况(我使用的是UICollectionViewFlowLayout
),我调整了collectionView:layout:sizeForItemAtIndexPath
方法来反映修改单元格的新的大小。 忘记那一部分,什么都不会发生在你的单元尺寸在所有如果你首先调用invalidateLayout
,然后尝试在动画尺寸的变化。
最奇怪的(至少对我来说),但重要的是你叫invalidateLayout
不是动画块内。 如果这样做,动画将不会显示平滑,但出问题和闪烁。
你要调用UIView
小号transitionWithView:duration:options:animations:completion:
方法与细胞作为论据transitionWithView
,而不是整个集合视图,因为它是你想获得动画,而不是整个采集的细胞。
我用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