【问题标题】:UICollectionView Decoration and Supplementary views can not be movedUICollectionView 装饰和补充视图不能移动
【发布时间】:2012-10-03 03:57:23
【问题描述】:

UICollectionView 的装饰和补充意见似乎是一个很大的谜。目前似乎几乎没有示例代码。我设法让这两种类型都在自定义布局中工作(有关详细信息,请参阅post)。只要他们保持在同一个位置,一切都很好(即如果他们的layoutAttributes.frame 没有改变)。

但是,一旦我为装饰或补充视图更改了 layoutAttributes 重新布局,它们就会在视觉上重复 - 即在其原始位置的背景中有一个副本,在其新位置有一个副本。如果我从 XIB 或完全在代码中实例化它们,则行为是相同的,并且对于普通单元格不会发生该行为。

起初我认为这是某种重绘问题,但这些“副本”在重新布局、重绘等后仍然存在。然而,它们不是真正的副本,因为从未调用过 layoutAttributesForDecorationView 等(仅对于新的位置)。 UICollectionView的后台似乎有一些缓存。

有没有人得到这个工作或有任何想法。我必须说我是 iOS 平台的新手,所以它也可能是简单的事情,比如设置“剪辑绑定”或“清除图形上下文”属性(我试过了,但可能是类似的)。

这让我发疯了,奇怪的是那里绝对没有示例代码。

我在问自己:装饰和补充观点不是要重新定位吗? (希望不会)

【问题讨论】:

  • 和你一样的问题。我不会重新定位它们,但是在集合视图上执行批量更新时它们会被复制。
  • 仅供参考,如果您不调用 performBatchUpdates 或不使用 CollectionView 中的 moveItem、deleteItem 或 insertItem,它不会出现。但是你失去了任何动画......
  • 我看到了同样的事情 - 但仅在重新加载数据时,而不是在重新布局时。我在自定义单元格中实现了 -prepareForReuse 以清除所有内容,但仍然看到重复数据(新数据覆盖在旧数据上)。
  • 这个运气好吗?还是有这个问题。

标签: objective-c ios ipad uicollectionview


【解决方案1】:

您好,这是一个老问题,但有一个答案。

实际上,当我实现自己的 Layout 对象时,我也遇到了这些问题,直到我意识到必须缓存您在自定义布局中创建的任何布局属性对象。在文档中实际上对此有一个非常模糊的引用(我现在不记得确切的位置),这很容易被误解。

基本上,一旦您为索引路径上的单元格请求了 layoutAttributes 对象,您应该保留属性对象(例如,将其保留在字典中,索引路径作为键)并为任何对象返回相同的属性对象以及对属性的所有后续请求。如果您不这样做,而是重新创建新的布局属性,批量更新的动画会导致严重的图形故障和伪影。

【讨论】:

  • 如果集合视图使用isEqual 来比较UICollectionViewLayoutAttributes 实例,使用深度比较覆盖isEqual 可能会解决问题,而无需保留对象。
【解决方案2】:

我有同样的问题。 UICOllectionview 似乎存在一些错误(这不是我第一次看到)。 我通过不使用“performBatchUpdates”来修复它。 我失去了动画 - 但在列表中没有不需要的视图。

【讨论】:

    【解决方案3】:

    我有类似的症状。我的问题是我在创建自定义布局时不小心包含了补充视图的 reuseID 而不是 kindID

    特别是我有这个(错误

    UICollectionViewLayoutAttributes *attributes = 
      [UICollectionViewLayoutAttributes
        layoutAttributesForSupplementaryViewOfKind:myViewReuseID
        withIndexPath:sectionIndexPath];
    

    什么时候我应该拥有这个(

    UICollectionViewLayoutAttributes *attributes = 
      [UICollectionViewLayoutAttributes
        layoutAttributesForSupplementaryViewOfKind:myViewKindID
        withIndexPath:sectionIndexPath];
    

    这意味着 prepareForReuse 永远不会被调用,我的旧观点也永远不会消失。相反,他们一直在堆积。

    【讨论】:

      【解决方案4】:

      我认为 Apple 至少会在装饰视图的情况下表明它们正在按预期工作。我遇到了同样的问题,因为我正在重新调整最后一部分的大小并尝试设置装饰视图以在它们更改时围绕这些部分。起初使用一个只有红色背景的简单视图,我的应用程序的整个背景都变成了红色,这让我很困惑。我随后在装饰视图的布局属性上将 alpha 更改为 0.3f,并且随着部分的更改,我能够看到它们相互叠加。

      我在UICollectionView 上的教程中读到的一句话让我真正意识到这可能是设计使然

      另一方面,装饰视图是“装饰性的”而不是 数据驱动:想想 iBooks 应用中的书架背景。

      关键是装饰视图不是数据驱动的,并且不应该随着数据的变化而变化,无论您是否能够在自定义布局中执行此操作。就像书架一样,书架的大小在创建后不会改变。

      【讨论】:

        【解决方案5】:

        我知道这是一个老问题,但是当使布局无效时,补充视图在各处重复出现问题时,我遇到了这个问题。我认为这是一个错误,我通过在我的布局对象中覆盖 invalidateLayout 并删除补充视图来修复它,如下所示:

        - (void)invalidateLayout {
            [super invalidateLayout];
            // Manually remove all suplementary views of a certain type
            /**
             ** This appears to be a BUG. Invalidate view does not remove suplementary view
             **     from the view hierachy. But they are Orphaned so stay on screen. 
             **/
            for (UIView *subview in [self.collectionView subviews]) {
                if ([subview isKindOfClass:[UICollectionReusableView class]]) {
                    [subview removeFromSuperview];
                }
            }
        }
        

        UICollectionReusableView 替换为留在屏幕上的可重用视图的类。

        希望这对某人有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-20
          • 2015-12-22
          • 2017-07-24
          • 1970-01-01
          • 1970-01-01
          • 2015-06-16
          • 1970-01-01
          相关资源
          最近更新 更多