在为UICollectionViewCell设置动画时,bounds.size和frame.size之间的相关性是什么

我已经阅读了几个post(比如https://stackoverflow.com/a/5340339/1084822和https://stackoverflow.com/a/15582466/1084822 )来调整带动画的UIView的大小,我们无法动画框架,我们必须混合使用bounds.size,bounds.origin和position。

但是,我无法找到这些属性与帧的属性之间的相关性。

我有一个自定义布局的UICollectionView。 删除单元格时,将刷新布局,并且每个单元格都通过prepareLayoutlayoutAttributesForElementsInRect:方法获取其新帧。 然后,调用finalizeCollectionViewUpdates方法(我们可以编辑动画)并最终移动并resize。

我通过细胞动画的试验和错误做了很多探索,这是我发现的:

  • 默认情况下,3个动画设置为我的可见单元格,即position,bounds.origin和bounds.size
  • 当我更改这些动画的from / to值时,只会影响单元格的POSITION,而不会影响它的SIZE

详细结果

默认值

当我坚持使用动画的默认值并使用这些日志检查它们的值时,

 - (void)finalizeCollectionViewUpdates { for(UICollectionViewCell* cell in [self.collectionView visibleCells]) { NSLog(@"cell: %@", cell); for(NSString* key in cell.layer.animationKeys) { CABasicAnimation* animation = (CABasicAnimation*)[cell.layer animationForKey:key]; NSLog(@"animation %@: from %@ to %@", key, animation.fromValue, animation.toValue); } } } 

我得到这个缩小的单元格(它的框架代表它的最终状态):

 cell: <PlayQueueSongCell: 0x7fbf1bc8ebe0; baseClass = UICollectionViewCell; frame = (53.3333 80; 480 480); opaque = NO; animations = { position=; bounds.origin=; bounds.size=; }; layer = > animation position: from NSPoint: {666.66666666666674, 0} to NSPoint: {0, 0} animation bounds.origin: from NSPoint: {0, 0} to NSPoint: {0, 0} animation bounds.size: from NSSize: {160, 160} to NSSize: {0, 0} 

这对于消费单元格(其框架代表其最终状态):

 cell: <PlayQueueSongCell: 0x7fbf1bd6cd00; baseClass = UICollectionViewCell; frame = (640 0; 640 640); opaque = NO; animations = { position=; bounds.origin=; bounds.size=; }; layer = > animation position: from NSPoint: {666.66666666666652, 0} to NSPoint: {0, 0} animation bounds.origin: from NSPoint: {0, 0} to NSPoint: {0, 0} animation bounds.size: from NSSize: {-160, -160} to NSSize: {0, 0} 

以慢动作查看结果: 在此处输入图像描述

没有bounds.size动画

当我用这个代码块删除bounds.size动画时,

 - (void)finalizeCollectionViewUpdates { for(UICollectionViewCell* cell in [self.collectionView visibleCells]) { for(NSString* key in cell.layer.animationKeys) { [cell.layer removeAnimationForKey:@"bounds.size"]; } } } 

我可以看到只有细胞的位置受到影响…… 在此处输入图像描述

bounds.size动画从(0,0)到(1000,1000)

当我用这个代码块将bounds.size的值更改为(0,0) – >(1000,1000)时:

 - (void)finalizeCollectionViewUpdates { for(UICollectionViewCell* cell in [self.collectionView visibleCells]) { for(NSString* key in cell.layer.animationKeys) { [cell.layer removeAnimationForKey:@"bounds.size"]; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds.size"]; [animation setFromValue:[NSValue valueWithCGSize:CGSizeZero]]; [animation setToValue:[NSValue valueWithCGSize:CGSizeMake(1000, 1000)]]; [animation setDuration:0.3]; [cell.layer addAnimation:animation forKey:@"bounds.size"]; } } } 

我仍然可以看到只有细胞的位置受到影响…… 在此处输入图像描述

由于单元格在动画开始之前获取其新帧并且bounds.size不会影响单元格的大小,因此我无法找到一种方法来平滑地更改其大小。

每个人都在谈论的bounds.size和frame.size之间的相关性是什么?如何设置单元格大小的动画?

我找到的解决方案是首先删除bounds.size动画,因为它以不需要的方式移动单元格。 然后,我创建一个transform.scale动画,该动画以一个模拟其先前大小的值开始,并以值1停止。

 if([cell.layer animationForKey:@"bounds.size"]) { [cell.layer removeAnimationForKey:@"bounds.size"]; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; animation.duration = 0.3; if(CGSizeEqualToSize(cell.frame.size, self.itemSize)) { //shrinking cell animation.fromValue = @1.333; animation.toValue = @1; } else { //expending cell animation.fromValue = @0.75; animation.toValue = @1; } [cell.layer addAnimation:animation forKey:@"transform.scale"]; }