我已经阅读了几篇文章(例如https://stackoverflow.com/a/5340339/1084822和https://stackoverflow.com/a/15582466/1084822),要通过动画来调整UIView的大小,我们无法为框架设置动画,我们必须使用混合了bounds.size,bounds.origin和position。
但是,我无法找到这些属性与框架属性之间的相关性。
我有一个带有自定义布局的UICollectionView。删除单元格后,将刷新布局,并且每个单元格都通过prepareLayout
和layoutAttributesForElementsInRect:
方法获取其新帧。然后,调用finalizeCollectionViewUpdates
方法(我们可以编辑动画)并最终移动并调整大小。
我通过细胞动画的反复试验做了很多探索,这就是我发现的:
当我坚持使用动画的默认值并使用这些日志检查它们的值时,
- (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=<CABasicAnimation: 0x7fbf1bf54e20>; bounds.origin=<CABasicAnimation: 0x7fbf1bf556b0>; bounds.size=<CABasicAnimation: 0x7fbf1bf557a0>; }; layer = <CALayer: 0x7fbf1bc8e9f0>>
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=<CABasicAnimation: 0x7fbf1bf55b70>; bounds.origin=<CABasicAnimation: 0x7fbf1bf55e20>; bounds.size=<CABasicAnimation: 0x7fbf1bf55f10>; }; layer = <CALayer: 0x7fbf1bd73200>>
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动画时,
- (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) - &gt; (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之间的相关性是什么?如何设置单元格大小的动画?
答案 0 :(得分:0)
我找到的解决方案是首先删除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"];
}