我正在编写自定义UICollectionViewFlowLayout
,并且我注意到当我调用initialLayoutAttributesForAppearingItemAtIndexPath:
时,将为所有部分调用initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath:
和performBatchUpdates:completion:
集合视图。结果是所有部分都将动画应用于它们,而不是只是新添加的部分。
[collectionView performBatchUpdates:^{
currentModelArrayIndex++;
[collectionView insertSections:[NSIndexSet indexSetWithIndex:currentModelArrayIndex]];
[collectionView reloadSections:[NSIndexSet indexSetWithIndex:currentModelArrayIndex-1]];
} completion:^(BOOL finished) {
[collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:currentModelArrayIndex] atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
}];
我到目前为止所尝试的是取消对performBatchUpdates:completion:
的调用,而不是简单的更新,但是现有的部分(所有部分)都是动画的。我已经提出了一个检查解决方案,以确保我只更改的布局属性最后一部分,但感觉很烦人。
if (decorationIndexPath.section == [(id<UICollectionViewDataSource>)self.collectionView.delegate numberOfSectionsInCollectionView:self.collectionView] - 1)
{
layoutAttributes.alpha = 0.0f;
layoutAttributes.transform3D = CATransform3DMakeTranslation(-CGRectGetWidth(layoutAttributes.frame), 0, 0);
}
这是仅仅为某些部分制作动画的正确方法吗?
答案 0 :(得分:7)
基本上,我们需要覆盖prepareForCollectionViewUpdates:
和finalizeCollectionViewUpdates
来跟踪我们要插入的部分。我有一个可变集,其中包含我们正在插入的部分的NSNumber
个实例。
-(void)prepareForCollectionViewUpdates:(NSArray *)updateItems
{
[super prepareForCollectionViewUpdates:updateItems];
[updateItems enumerateObjectsUsingBlock:^(UICollectionViewUpdateItem *updateItem, NSUInteger idx, BOOL *stop) {
if (updateItem.updateAction == UICollectionUpdateActionInsert)
{
[insertedSectionSet addObject:@(updateItem.indexPathAfterUpdate.section)];
}
}];
}
-(void)finalizeCollectionViewUpdates
{
[super finalizeCollectionViewUpdates];
[insertedSectionSet removeAllObjects];
}
接下来,在设置项目和装饰视图的初始布局属性时,检查索引路径的部分是否包含在该集合中。
-(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingDecorationElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)decorationIndexPath
{
UICollectionViewLayoutAttributes *layoutAttributes;
if ([elementKind isEqualToString:AFCollectionViewFlowLayoutBackgroundDecoration])
{
if ([insertedSectionSet containsObject:@(decorationIndexPath.section)])
{
layoutAttributes = [self layoutAttributesForDecorationViewOfKind:elementKind atIndexPath:decorationIndexPath];
layoutAttributes.alpha = 0.0f;
layoutAttributes.transform3D = CATransform3DMakeTranslation(-CGRectGetWidth(layoutAttributes.frame), 0, 0);
}
}
return layoutAttributes;
}
-(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
UICollectionViewLayoutAttributes *layoutAttributes;
if ([insertedSectionSet containsObject:@(itemIndexPath.section)])
{
layoutAttributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
layoutAttributes.transform3D = CATransform3DMakeTranslation([self collectionViewContentSize].width, 0, 0);
}
return layoutAttributes;
}
我从这些方法返回nil
,否则因为nil
是默认值。
这也有更好的旋转动画效果。