使用子类 collectionViewFlowLayout 时出现奇怪的错误

Posted

技术标签:

【中文标题】使用子类 collectionViewFlowLayout 时出现奇怪的错误【英文标题】:when using subclassed collectionViewFlowLayout I'm getting weird error 【发布时间】:2015-10-24 14:29:22 【问题描述】:

我创建了collectionViewFlowLayout 的子类。之后,我实现了以下代码:

override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? 
        let attr = self.layoutAttributesForItemAtIndexPath(itemIndexPath)
        attr?.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(0.8, 0.8), CGFloat(M_PI))
        attr?.center = CGPointMake(CGRectGetMidX(self.collectionView!.bounds), CGRectGetMidY(self.collectionView!.bounds))
        return attr
    

当我使用performBatchUpdates: 方法删除集合视图中的项目时,调试器会抛出此错误消息。删除实际上成功并且正在完全工作,但我对这个调试器输出有点困惑。有人可以解释一下我应该做些什么来取悦调试器吗?我真的不明白应该添加什么代码以及在哪里添加。

//错误信息

2015-08-02 12:39:42.208 nameOfMyProject[1888:51831] 仅记录一次 对于 UICollectionViewFlowLayout 缓存不匹配的帧 2015-08-02 12:39:42.209 nameOfMyProject [1888:51831] UICollectionViewFlowLayout 已缓存索引路径 length = 2, path = 0 - 11 的帧不匹配 - 缓存值: 106.13333333333333, 131.13333333333333, 75.733333333333348, 75.733333333333348;期望值:192.5, 288, 94.666666666666671, 94.666666666666671

2015-08-02 12:39:42.209 nameOfMyProject[1888:51831] 这很可能 发生是因为流布局子类 nameOfMyProject.ShopLayout 正在修改 UICollectionViewFlowLayout 返回的属性而不 复制它们

2015-08-02 12:39:42.209 nameOfMyProject[1888:51831] 快照 未渲​​染的视图会导致空快照。确保 您的视图在快照之前至少渲染过一次,或者 屏幕更新后的快照。

【问题讨论】:

这只是从 Xcode 7 开始发生的吗?自从更新到 Xcode 7(并安装 ios9)以来,我也发生了非常相似的事情。我是 Obj-C,不是 swift,但错误是告诉您在更改属性之前您没有复制属性。在操作它们之前,我尝试过像NSArray *allAttributesInArray = [[super layoutAttributesForElementsInRect:rect] copy]; 这样的操作,但这似乎也不起作用。 在 xcode 7 之前我从未使用过集合视图。我最终使用了一个没有子类化的普通旧 flowLayout,所以我无法真正提供答案 @wanderingme 你知道如何解决这个问题了吗?我也有同样的问题,但没有任何帮助解决它。 我做到了,但是对于 Obj-C 并使用了一个名为 TLLayoutTransitioning 的自定义子类。我在这里提到了我的解决方法:github.com/wtmoose/TLLayoutTransitioning/issues/26 TL;DR 版本:我在两个 UICollectionViewFlowLayout 之间转换之前重新加载了 UICollectionView 数据。 【参考方案1】:

发生错误是因为您在没有先复制属性的情况下操作该属性。所以这应该可以解决错误:

override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? 
    let attr = self.layoutAttributesForItemAtIndexPath(itemIndexPath)?.copy() as! UICollectionViewLayoutAttributes
    // manipulate the attr
    return attr

当您在layoutAttributesForElementsInRect(rect: CGRect) 中遇到同样的错误时,您必须复制数组中的每个项目,而不仅仅是复制数组:

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? 
        let attributes = super.layoutAttributesForElementsInRect(rect)
        var attributesCopy = [UICollectionViewLayoutAttributes]()
        for itemAttributes in attributes! 
            let itemAttributesCopy = itemAttributes.copy() as! UICollectionViewLayoutAttributes
            // manipulate itemAttributesCopy
            attributesCopy.append(itemAttributesCopy)
        
        return attributesCopy
     

【讨论】:

复制 layoutAttributesForElementsInRect 中的所有属性解决了警告。 @Ranjit 你看过上面cmets中提到的github问题吗? (github.com/wtmoose/TLLayoutTransitioning/issues/26) @joern,看着它。

以上是关于使用子类 collectionViewFlowLayout 时出现奇怪的错误的主要内容,如果未能解决你的问题,请参考以下文章

子类要调用父类的方法,必须使用super关键字.对吗?

iOS:使用 nib 子类化 UITableViewCell,进入 UIView(不是视图控制器)子类

使用“this”调用超类方法的子类

在java中子类若要继承父类,需要使用的关键字是啥

java中父类与子类的关系以及使用

C++ 中,类的继承:父类当使用虚函数时候,子类对该函数进行重写的话,属于子类成员函数对虚函数的覆盖!