【问题标题】:Subclassing UICollectionViewLayoutAttributes子类化 UICollectionViewLayoutAttributes
【发布时间】:2012-09-14 03:39:29
【问题描述】:

我最近开始使用很棒的 UICollectionView API,取得了合理的进展,但几乎整天都被困在一个问题上,希望有人能帮助我:

我需要为某些单元格的属性添加一些自定义细节。 为了做到这一点,正确的方法似乎是继承 UICollectionViewLayoutAttributes 并将我需要的属性添加到我的子类中。到目前为止一切都很好,除了当我返回我的 LayoutAttributesSubclass 时,我总是得到以下错误,不知何故晦涩:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: key cannot be nil'

在尝试跟踪此问题一段时间后,我的印象是该错误与代表元素种类有关,并且代表元素类别在我的子类实例中为 nil。但是这些属性是只读的,所以我不能设置它们。 我设法通过作弊以某种方式绕过错误,获取常规 UICollectionViewAttributes 实例,然后使用 object_setClass 将其更改为 LayoutAttributesSubclass,但这会引发大量其他问题,而且对我来说似乎相当阴暗。

简而言之,有谁知道上面的错误是什么意思,以及如何正确创建/使用 UICollectionViewLayoutAttributes 子类?

【问题讨论】:

    标签: ios ios6 uicollectionview


    【解决方案1】:

    设置自定义属性时,您需要继承 UICollectionViewLayoutAttributes 子类 UICollectionViewLayout 并通过覆盖 UICollectionViewLayout 类中的 +(Class)layoutAttributesClass 来“声明”您的自定义属性子类类名称。当您使用工厂方法实例化/出列布局属性对象时,系统会调用该类方法来查看是否提供自定义类。

    @interface YourCustomCollectionViewAttributes : UICollectionViewLayoutAttributes
    
    @property (nonatomic)               UIEdgeInsets        myCustomProperty                        
    
    @end
    
    @interface YourCustomCollectionViewLayout : UICollectionViewLayout
    
    @end
    
    @implementation YourCustomCollectionViewLayout
    
    + (Class)layoutAttributesClass
    {
        return [IRTableCollectionViewLayoutAttributes class];
    }
    
    @end
    

    根据文档,这是正确的,应该可以防止您遇到的特定错误。此外,当您实现自定义 iVar 时,请务必实现对 -(id)copyWithZone: 的覆盖,否则 UICollectionView 将丢失您已应用于自定义集合视图对象的任何自定义值。

    【讨论】:

    • 感谢您的回答,+layoutAttributesClass 确实是要走的路。我希望有一个不同的解决方案,因为我只想将我的 layoutattributes 子类用于某些特定项目,但显然无法做到。
    • 丢弃自定义值的问题是因为我们必须实现 -copyWithZone: 因为 UICollectionViewLayoutAttributes 实现并使用了 NSCopying
    • 感谢 griotspeak,您说得非常正确——而且如此简单。考虑到这一点,我会修改我的答案。
    • 这对我不起作用,我在调用 layoutAttributesClass 之前得到 NSInvalidArgumentException,这是由于使用 [[MyCollectionViewLayoutAttributes alloc] init] 而不是 [MyCollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]。我确实设置了 indexPath 并覆盖了代表元素类别。有什么想法吗?
    • @griotspeak 的复制构造函数注释非常重要。如果您注意到您设置的属性在 applyLayoutAttributes: 之前没有“保留”,请实现一个复制构造函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多