UICollectionView:animation单元大小更改select

我想要做的是改变一个UICollectionViewCell的大小,并为单元格被选中时的animation改变。 我已经设法通过在cellView collectionView: didSelectItemAtIndexPath:select一个单元格,然后在我的UICollectionView上调用reloadData来显示选定单元格的大小。

尽pipe如此,这一切都发生了,我不知道如何让这个变化的大小animation。 有任何想法吗?

我已经select了Animate uicollectionview单元格 ,但答案是对于我而言没有具体说明,我还没有弄清楚它是否也可以帮助我。

 [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方法内部沿着这些线索玩东西。

在Chase Roberts的帮助下,我现在find了解决我的问题的方法。 我的代码基本上是这样的:

 // 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. 最重要的步骤之一就是使用的UICollectionView.collectionViewLayout上的invalidateLayout调用。 如果你忘记了这一点,很可能会发生这样的情况:细胞会长在你的collections的边界上 – 这是你最不可能发生的事情。 另外考虑一下你的代码应该在你的布局中展示你的单元格的新大小。 在我的情况下(我使用UICollectionViewFlowLayout ),我调整了collectionView:layout:sizeForItemAtIndexPath方法以反映修改的单元格的新大小。 忘记这个部分,如果你第一次调用invalidateLayout ,然后尝试animation变化的大小,根本就没有任何细胞大小会发生变化。

  2. 最奇怪的(至less对我来说),但重要的是你不在animation块内调用invalidateLayout 。 如果这样做,animation将不会显示平滑,但闪烁和闪烁。

  3. 你必须调用UIViewtransitionWithView:duration:options:animations:completion:方法,把cell作为transitionWithView参数,而不是整个集合视图,因为它是你想要获得animation的单元格,而不是整个集合。

  4. 我使用我的单元格的intrinsicContentSize方法返回我想要的大小 – 在我的情况下,我扩大和缩小单元格的宽度,以显示一个button或隐藏它,这取决于单元格的select状态。

我希望这会帮助一些人。 对我来说,花了几个小时才能弄清楚如何使animation正常工作,所以我试图从其他人那里解脱出来。

对单元格大小进行animation处理对于集合视图的工作方式与对表格视图的工作方式相同。 如果你想animation的单元格大小,有一个数据模型,反映了单元格的状态(在我的情况下,我只是使用一个标志(CollectionViewCellExpanded,CollectionViewCellCollapsed),并相应地返回一个CGSize。

当您调用并清空performBathUpdates调用时,该视图会自动生成animation。

 - (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) { }]; } 

我已经通过使用-setCollectionViewLayout:animated:创build相同集合视图布局的新实例成功地animation更改。

例如,如果您使用的是UICollectionViewFlowLayout ,那么:

 // Make sure that your datasource/delegate are up-to-date first // Then animate the layout changes [collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES]; 

这是我find的最简单的解决scheme – 像魅力一样工作。 stream畅的animation,并不会搞乱布局。

迅速

  collectionView.performBatchUpdates({}){} 

OBJ-C

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

块(斯威夫特closures)应该故意留空!

为单元格大小设置animation效果的好方法是重写collectionViewCell本身的isSelected。

 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) } } } } 

这对我有效。

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