如何将自定义 UICollectionViewLayoutAttributes 向下转换为 apply() 方法?

How to downcast custom UICollectionViewLayoutAttributes to apply() method?

我只是找不到如何在自定义单元格的 apply() 方法中访问自定义布局属性。

我必须为我的 CollectionViewLayoutAtrributes 实现自定义布局属性,所以我将它们替换class。到目前为止效果很好:

class TunedLayoutAttributes: UICollectionViewLayoutAttributes {

    var customLayoutAttributeValue: CGFloat = 1000

    override func copy(with zone: NSZone?) -> Any {
        let copy = super.copy(with: zone) as! TunedLayoutAttributes
        customLayoutAttributeValue = customLayoutAttributeValue
        return copy
    }

    override func isEqual(_ object: Any?) -> Bool {
        if let attributes = object as? TunedLayoutAttributes {
            if attributes. customLayoutAttributeValue == customLayoutAttributeValue {
                return super.isEqual (object)
            }
        }
        return false
    }
}

该值必须根据用户滚动交互动态更改。 现在我需要我的自定义单元格在来自自定义 UICollectionViewLayout class 的 invalidateLayout 调用后更新它们的外观。据我所知,这通常也可以通过覆盖单元格 classes apply(_ layoutAttributes: UICollectionViewLayoutAttributes) 方法来完成。

通常是这样的:

override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {

    let newFrame = // calculations here. CGRect(....) 
    layoutAttributes.frame = newFrame
}




现在缺少的化学物质:

与上面的 apply() 示例不同,我的新 customLayoutAttributeValue(当然?)不是方法中 layoutAttributes: 的一部分。

所以我尝试将 layoutAttributes 向下转换为我的自定义 class,如下所示:

override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {

    let tunedLayoutAttributes = layoutAttributes as! TunedLayoutAttributes
    tunedLayoutAttributes.customLayoutAttributeValue = // calculation here. 
}

那么如何在 apply() 方法中访问 tunedLayoutAttributes? 任何帮助表示赞赏。感谢阅读!

您在这里为自己提供了解决方案。 UICollectionViewLayoutAttributes(当然)不知道 customLayoutAttributeValue,因此您必须转换为适当的 class(TunedLayoutAttributes,在您的情况下)。

现在为了让 apply(_:) 真正给你 TunedLayoutAttributes 而不仅仅是普通的 UICollectionViewLayoutAttributes,你需要告诉你的 UICollectionViewLayout subclass在为布局中的项目出售布局属性时使用自定义 class (TunedLayoutAttributes)。

您可以通过在布局子 class 中覆盖 class var layoutAttributesClass 来做到这一点。

请注意,如果您在布局子 class 中重写布局属性销售方法(layoutAttributesForElements(in:) 和朋友),则需要 return TunedLayoutAttributes一切正常。

另请注意,在执行集合视图布局过程时,UIKit 经常在幕后复制属性,因此请确保您的 copyisEqual 方法按预期工作。 (例如,传递给 apply(_:) 的属性对象不是(必然)您的布局出售的对象,而是副本。

编辑

正如评论中所讨论的那样,您应该将强制转换 as! 替换为 if let as? 转换,以防止在 apply(_:) 实际上通过普通 UICollectionViewLayoutAttributes 时发生崩溃。