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

时间:2018-07-16 11:28:05

标签: swift uicollectionview uicollectionviewcell uicollectionviewlayout downcast

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

我必须为CollectionViewLayoutAtrributes实现自定义布局属性,因此我将它们子类化。到目前为止,效果很好:

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
    }
}

该值必须根据用户滚动交互而动态更改。 现在,在自定义invalidateLayout类进行UICollectionViewLayout调用之后,我需要自定义单元格来更新其外观。据我所知,通常也可以通过重写单元格类apply(_ layoutAttributes: UICollectionViewLayoutAttributes)方法来实现。

通常是这样的:

override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {

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




现在缺少化学物质:

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

因此,我尝试将layoutAttributes转换为自定义类,如下所示:

override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {

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

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

1 个答案:

答案 0 :(得分:3)

您有点在这里给自己解决方案。 UICollectionViewLayoutAttributes(当然)不了解customLayoutAttributeValue,因此您必须转换为适当的类(在您的情况下为TunedLayoutAttributes)。

现在,为了使apply(_:)实际给您TunedLayoutAttributes而不只是普通的UICollectionViewLayoutAttributes,您需要告诉UICollectionViewLayout子类使用您的自定义类({{ 1}})为版面中的项目出售版面属性时。

您可以通过覆盖布局子类中的TunedLayoutAttributes来实现。

请注意,如果您在布局子类中覆盖布局属性销售方法(class var layoutAttributesClass和朋友),则需要在其中返回layoutAttributesForElements(in:)才能使整个工作正常进行。

还要注意,TunedLayoutAttributes在执行集合视图布局遍历时经常在后台复制属性,因此请确保UIKitcopy方法正常工作。 (例如,传递给isEqual的属性对象不是(不一定)您的布局出售的对象,而是副本。

编辑

如评论中所述,您应使用apply(_:)强制转换as!替换强制转换if let as?,以防止在apply(_:)实际上经过普通UICollectionViewLayoutAttributes时崩溃。