Подкласс UICollectionViewLayoutAttributes возвращает nil в пользовательских свойствах

Я подклассифицировал класс UICollectionViewLayoutAttributes и добавил несколько настраиваемых свойств.

В моем классе UICollectionViewLayout я переопределяю статическую + (Class)layoutAttributesClass, и я возвращаю свой новый класс атрибутов.

В моем классе UICollectionViewLayout я переопределяю -(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect, и я устанавливаю значения в пользовательские свойства.

Я могу проверить класс атрибутов прямо там и увидеть, что пользовательские свойства установлены правильно.

Итак, наконец, мне нужно получить эти свойства в UICollectionViewCell, поэтому я переопределяю -(void) applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes для извлечения значений в пользовательском классе UICollectionViewLayoutAttributes, YET они равны нулю. Как будто я их никогда не ставил.

Все остальные атрибуты работают отлично, включая преобразования и т.д. Так ясно, что я делаю что-то неправильно. Просьба сообщить.

Входит в HeaderFile моего пользовательского класса

@interface UICollectionViewLayoutAttributesWithColor : UICollectionViewLayoutAttributes

@property (strong,nonatomic) UIColor *color;

@end

и вот реализация. Как вы можете видеть, ничего особенного

@implementation UICollectionViewLayoutAttributesWithColor

@synthesize color=_color;

@end

Ответ 1

вы будете рады узнать, что ответ прост. Вам просто нужно переопределить copyWithZone: поскольку UICollectionViewAttributes реализует протокол NSCopying. Что происходит, код Apple создает копии объекта пользовательских атрибутов, но поскольку вы не реализовали copyWithZone, ваши пользовательские атрибуты не копируются в новый объект. Вот пример того, что вам нужно сделать:

@interface IRTableCollectionViewLayoutAttributes : UICollectionViewLayoutAttributes {
    CGRect _textFieldFrame;
}

@property (nonatomic, assign) CGRect  textFieldFrame;

@end

и реализация:

- (id)copyWithZone:(NSZone *)zone
{
    IRTableCollectionViewLayoutAttributes *newAttributes = [super copyWithZone:zone];
    newAttributes->_textFieldFrame = _textFieldFrame;

    return newAttributes;
}

Ответ 2

Проблема удаления пользовательских значений заключается в том, что мы должны реализовать -copyWithZone: поскольку UICollectionViewLayoutAttributes реализует и использует NSCopying

Ответ 3

Похоже, вы пытаетесь применить атрибуты макета к ячейке. Это можно сделать следующим образом:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //Get Cell
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MY_CELL" forIndexPath:indexPath];

    //Apply Attributes
    UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    [cell applyLayoutAttributes:attributes];

    return cell;
}

Однако в моей реализации UICollectionView я просто добавил пользовательские свойства в свой подкласс UICollectionViewCell, не являющийся подклассом UICollectionViewLayoutAttributes. Я думаю, что в большинстве случаев подклассификация UICollectionViewCell более эффективна:

@interface ColoredCollectionCell : UICollectionViewCell
@property (strong,nonatomic) UIColor *color;
@end

@implementation ColoredCollectionCell
// No need to @synthesize in iOS6 sdk
@end

В вашем контроллере просмотра коллекции:

- (UICollectionViewCell*)collectionView:(UICollectionView*)cv cellForItemAtIndexPath:(NSIndexPath*)indexPath
{
    //Get the Cell
    ColoredCollectionCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"MY_CELL" forIndexPath:indexPath];

    //Get the color from Array of colors
    UIColor *thisColor = self.colorsArray[indexPath.item];

    //Set cell color
    cell.color = thisColor;

    return cell;

}