【发布时间】:2013-10-31 21:47:25
【问题描述】:
我看到UICollectionView 在旋转设备时出现了一些带有自定义布局(UICollectionViewLayout 的子类)的神秘行为。
我有一个简单的水平滚动单元格行。当将设备从纵向旋转到横向时,以前不可见的其他单元格变得可见,并且那些出现的单元格的动画是错误的(它使用熟悉的重影效果,我认为这是收藏视图的某种默认动画效果布局)。请注意此动画中最左侧出现的单元格:
关于自定义布局设置的一些细节:
-
shouldInvalidateLayoutForBoundsChange:返回YES。 -
layoutAttributesForItemAtIndexPath:在字典中缓存尚未创建的属性。 - 在
layoutAttributesForElementsInRect:中,我手动计算哪些单元格应该可见,并在返回它们的属性之前每次稍微调整它们的centre属性。
然后我有以下代码来处理初始/最终布局属性:
- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds
{
[super prepareForAnimatedBoundsChange:oldBounds];
self.animatingBoundsChange = YES;
}
- (void)finalizeAnimatedBoundsChange
{
[super finalizeAnimatedBoundsChange];
self.animatingBoundsChange = NO;
}
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
if (self.animatingBoundsChange) {
// If the view is rotating, appearing items should animate from their current attributes (specify `nil`).
// Both of these appear to do much the same thing:
//return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
return nil;
}
return [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
}
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
if (self.animatingBoundsChange) {
// If the view is rotating, disappearing items should animate to their new attributes.
return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
}
return [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];
}
在我看来,新出现的单元格的初始布局属性在某种程度上是不正确的(毕竟它结束在正确的位置)。但是,当我记录从initalLayout... 方法返回的布局属性的center 属性时,一切看起来都是正确的——全部沿水平轴均匀分布。
单元格动画不正确的唯一区别是当调用initialLayout... 方法时,它的单元格没有返回到[collectionView visibleCells] 数组中。但是,它前面的 layoutAttributesForElementsInRect: 确实正确地识别出它的布局属性是必需的。
那么发生了什么?对幕后发生的事情的一些见解会非常有帮助...UICollectionView 似乎是一个巨大的黑匣子。
【问题讨论】:
-
如果 iOS 检测到过渡不能顺利发生,即这种情况,它将在与现有单元格碰撞的任何单元格上使用交叉淡入淡出动画。这在 iOS7 中 UICollectionViews 的 WWDC 视频中有记录。
-
@Arun_k 这个问题似乎与这个问题无关——他们要求澄清为什么
initial/finalLayout...会被轮换调用,事实上他们确认添加上述代码可以防止 交叉渐变动画。此问题涉及动画边界更改后呈现的其他单元格。 -
@Jeff 谢谢,你能提供特定视频的名称吗?我知道默认的淡入淡出动画,但我的理解是这应该可以使用
initial/finalLayout...方法完全自定义。如果提供了初始位置,我不明白为什么出现的单元格不能流畅地动画。 -
使用视图控制器的 UIKit 动态和自定义转换的高级技术。 developer.apple.com/wwdc/videos
标签: ios uicollectionview uicollectionviewlayout