ios - 具有自定义布局的 UICollectionView 界面旋转

标签 ios uicollectionview uicollectionviewlayout

当旋转设备时,我从带有自定义布局(UICollectionViewLayout 的子类)的 UICollectionView 中看到了一些神秘的行为。

我有一行简单的水平滚动单元格。当将设备从纵向旋转到横向时,以前不可见的其他单元格变得可见,并且那些出现的单元格的动画是错误的(它使用熟悉的重影效果,我认为这是 Collection View 的某种默认动画效果布局)。请注意此动画中最左侧出现的单元格:

UICollectionViewRotationGhosting

关于自定义布局设置的一些细节:

  • 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... 方法被调用。但是,它前面的 layoutAttributesForElementsInRect: 确实正确地标识了它的布局属性是必需的。

这是怎么回事?深入了解引擎盖下发生的事情会很有帮助……UICollectionView 看起来像一个巨大的黑盒子。

最佳答案

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

这个问题进一步阐明了这个问题:initialLayoutAttributesForAppearingItemAtIndexPath fired for all visible cells, not just inserted cells

关于ios - 具有自定义布局的 UICollectionView 界面旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19527772/

相关文章:

ios - 用于 Retina iPad 图像的正确后缀是什么?

ios - 如何布局具有不同高度的自定义 UITableViewCell

ios - NSURLConnection - didReceiveData 没有被调用 - iOS 和 ARC

ios - CollectionView 方向问题

ios - 插入 UICollectionViewCell 时在 iOS 10.3.1 上崩溃

iphone - 如何使用左侧或右侧移动UILabel?

ios - UICollectionView:如何在不长按的情况下重新排序

ios - UICollectionViewDelegateFlowLayout Edge Insets 未被 sizeForItemAt 函数识别?

iphone - 如何让 UICollectionViewFlowLayout 的单元格跨越多行?

ios - 在没有重新加载方法的情况下调整 UICollectionView 的单元格大小