简体   繁体   中英

Animate on insertion/removal supplementary views

currently I'm studying custom UICollectionViewLayout by this lesson: https://www.objc.io/issues/12-animations/collectionview-animations . Everything is fine with static data, but when I'm trying to delete an item, error 'NSRangeException' occurs in method

layoutAttributesForItemAtIndexPath:

I suppose it is related to getting attributes for a removed item, but it is called after I remove this item. I attempted to fix it by adding additional variable 'removedItem' and it worked, but I'm not sure if it is a common practice as it sounds like a workaround and would like to hear advice on this.

The main question is how to animate supplementary view on insert or removal of an collection view item. I have created layout as follows in attachment: 我的布局

where cells are bordered items with cube in center and supplementary views are colored views that are placed below every cell. For animation of items and cells I use these methods:

-(UICollectionViewLayoutAttributes*)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {
UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:itemIndexPath];

attr.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(0.2, 0.2), M_PI);
attr.center = CGPointMake(CGRectGetMidX(self.collectionView.bounds), CGRectGetMaxY(self.collectionView.bounds));

return attr;
}
-(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingSupplementaryElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath {...}
-(UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {...}
-(UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingSupplementaryElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath {...}

For example to insert an item I use standard method:

[self.sampleCollectionView insertItemsAtIndexPaths:@[indexPath]];

Which leads to proper item animation, but supplementary view just appears without animation. When I call

deleteItemsAtIndexPaths: 

supplementary view not only doesn't have animation of removal, but also remains visible and is removed after I start scrolling or call invalidateLayout on my custom layout. So, is there any way to animate supplementary views? Thanks in advance.

To remove supplementary views use

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingSupplementaryElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath {
    UICollectionViewLayoutAttributes *attributes = [super finalLayoutAttributesForDisappearingSupplementaryElementOfKind:elementKind atIndexPath:elementIndexPath];
    attributes.alpha = 0;
    return attributes;
}

One way of animated disappear I've found - animation block in

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath  

it must be tied to view with some KVO (looks like hack)

-----

Another approach might be to override prepareLayout where you will build attributes for all supplementary views, you need. When you don't need some supplementary view anymore, do not simply remove it's attributes from your layouInfoDictionary and layoutAttributesArray which you use in

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
and 
- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath

Create proper attributes for hidden items instead. And in next iteration of prepareLayout these attributes will be removed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM