【问题标题】:UICollectionView interface rotation with custom layout带有自定义布局的 UICollectionView 界面旋转
【发布时间】: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


【解决方案1】:

the answer that Arun_k linked to 为基础,除了nil 出现的新单元格之外,您似乎可能需要返回与initialLayoutAttributesForAppearingItemAtIndexPath: 不同的内容。 nil 适用于已经在屏幕上的单元格,但可能不适合返回新单元格。也许您可以尝试在此方法中为所有单元格返回一个固定的UICollectionViewLayoutAttributes 值,看看它是否会改变新插入的单元格的动画行为,然后从那里继续。

这个问题更能说明这个问题:initialLayoutAttributesForAppearingItemAtIndexPath fired for all visible cells, not just inserted cells

【讨论】:

  • 感谢您的回复。不幸的是,正如我在我的问题中所说,返回一个非零值 ([self layoutAttributesForItem...]) 没有任何区别,即使记录返回的值显示所有单元格的正确初始位置,包括新出现的单元格。我会按照建议到处玩,看看能不能找到更多。
猜你喜欢
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
相关资源
最近更新 更多