I've read on several posts (like https://stackoverflow.com/a/5340339/1084822 and https://stackoverflow.com/a/15582466/1084822) that to resize a UIView with animation, we can't animate the frame and we must do it with a mix of bounds.size, bounds.origin and position.
However, I can't find what is the correlation between those properties and those of the frame.
I have a UICollectionView with a custom layout. When a cell is deleted, the layout is refreshed and every cell gets its new frame through the prepareLayout
and layoutAttributesForElementsInRect:
methods. Then, the finalizeCollectionViewUpdates
method (where we can edit animations) gets called and finally the cells move and get resized.
I've done a lot of exploration by trial and error with the cells animation and here is what I found :
- 3 animations are set by default to my visible cells which are position, bounds.origin and bounds.size
- when I change the from/to values of these animations, only the POSITION of the cell is affected, and never its SIZE
Detailed results
Default values
When I stick to the default values of the animations and check their values with these logs,
- (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);
}
}
}
I get this for the shrinking cell (its frame represent its final state):
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}
and this for the expending cell (its frame represent its final state):
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}
See the result in slow motion:
No bounds.size animation
When I remove the bounds.size animation with this block of code,
- (void)finalizeCollectionViewUpdates {
for(UICollectionViewCell* cell in [self.collectionView visibleCells]) {
for(NSString* key in cell.layer.animationKeys) {
[cell.layer removeAnimationForKey:@"bounds.size"];
}
}
}
I can see that only the POSITION of the cell is affected...
bounds.size animation from (0,0) to (1000,1000)
And when I change the values of bounds.size to (0,0) -> (1000,1000) with this block of code:
- (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"];
}
}
}
I can still see that only the POSITION of the cell is affected...
Question
Since the cell gets its new frame just before the animation starts and the bounds.size does not affect the cell's size, I can't find a way to change its size smoothly.
What is the correlation between the bounds.size and the frame.size that everyone is talking about and how can one animate the size of the cell?