Как я могу добавить дополнительное представление заголовка/метки для каждой ячейки в UICollectionViewFlowLayout?

Все примеры, которые я видел, используют дополнительный вид в качестве верхних или нижних колонтитулов. Мне нужно добавить метку выше и/или ниже каждой ячейки в моем макете потока.

Сначала я думал, что все, что мне нужно сделать, это зарегистрировать класс для дополнительного вида, а затем реализовать коллекциюViewForSupplementaryElementOfKindAtIndexPath, и все будет готово, но, похоже, < em>FlowLayout по умолчанию поддерживает только верхние и нижние колонтитулы.

Apple docs, кажется, предполагает, что что-то еще потребует усилий по созданию подклассов FlowLayout.

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

Я думаю, что смогу сделать это, создав подкласс UICollectionViewFlowLayout.

Но я не уверен, как сказать макету потока запрашивать дополнительный вид для каждой ячейки. Простая регистрация класса для представления поддержки не заставляет макет вызывать layoutAttributesForSupplementaryViewOfKind. В нынешнем виде это никогда не вызывается в моем подклассе. Я подумал, что если я зарегистрирую класс для представления поддержки, он должен запрашивать представление поддержки для каждого из элементов в моем разделе... это кажется неверным предположением.

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


person topwik    schedule 04.06.2013    source источник
comment
Не могли бы вы обновить свой UITableViewCell, чтобы просто включить метку верхнего и нижнего колонтитула? Это было бы намного проще, чем управлять кучей дополнительных представлений.   -  person Derrick Hathaway    schedule 04.06.2013
comment
@DerrickHathaway да, это была первоначальная идея. У меня просто была метка в моем UICollectionViewCell, которая была бы закреплена вверху. Но поскольку размер ячейки является динамическим, а текст может быть довольно длинным, иногда метка была слишком большой для размера ячейки, поэтому я хотел попробовать разделить метку заголовка в качестве дополнительной метки заголовка.   -  person topwik    schedule 04.06.2013
comment
... должен быть довольно прямой способ сделать это   -  person topwik    schedule 04.06.2013
comment
Единственный способ сделать это, как вы предложили: подкласс UICollectionViewFlowLayout и предоставить свои собственные типы SupplementaryViews. И если дополнительные метки довольно значительны по размеру, вы, возможно, даже не сможете сделать это с помощью макета потока, потому что я не думаю, что макет потока будет учитывать пространство, используемое вашими собственными дополнительными представлениями.   -  person Derrick Hathaway    schedule 04.06.2013


Ответы (1)


Что ж, вам нужно будет добавить атрибуты, описывающие многократно используемое представление для каждой ячейки, для которой оно вам нужно. вы можете добавить эти атрибуты для каждой ячейки на основе атрибутов, которые уже должны быть там для размещения ваших ячеек. вы можете сделать это в layoutAttributesForElementInRect.

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    //first get a copy of all layout attributes that represent the cells. you will be modifying this collection.
    NSMutableArray *allAttributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy]; 

    //go through each cell attribute
    for (UICollectionViewLayoutAttributes *attributes in [super layoutAttributesForElementsInRect:rect])
    {
        //add a title and a detail supp view for each cell attribute to your copy of all attributes
        [allAttributes addObject:[self layoutAttributesForSupplementaryViewOfKind:SomeCellDetailsKind atIndexPath:[attributes indexPath]]];
        [allAttributes addObject:[self layoutAttributesForSupplementaryViewOfKind:SomeCellTitleKind atIndexPath:[attributes indexPath]]];
    }

    //return the updated attributes list along with the layout info for the supp views
    return allAttributes;
}

-(UICollectionViewLayoutAttributes*) layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
    //create a new layout attributes to represent this reusable view
    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:kind withIndexPath:indexPath];

    if(attrs){

        //get the attributes for the related cell at this index path
        UICollectionViewLayoutAttributes *cellAttrs = [super layoutAttributesForItemAtIndexPath:indexPath];

        if(kind == SomeCellDetailsKind){
            //position this reusable view relative to the cells frame
            CGRect frame = cellAttrs.frame;
            frame.origin.y += (frame.size.height - _detailHeight);
            frame.size.height = _detailHeight;
            attrs.frame = frame;
        }

        if(kind == SomeCellTitleKind){
            //position this reusable view relative to the cells frame
            CGRect frame = cellAttrs.frame;
            frame.origin.y -= _titleHeight; //+= frame.size.height; //( - frame.size.height;
            frame.size.height = _titleHeight;
            attrs.frame = frame;
        }
    }

    return attrs;
}

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

И, как упомянул Деррик Хэтэуэй, макет потока не будет измерять высоту строк с учетом высоты вспомогательных представлений, поэтому обязательно отрегулируйте минимальную высоту строки в представлении коллекции соответствующим образом.

person topwik    schedule 25.06.2013
comment
Большое спасибо за этот ответ. Я знаю, что прошло больше года, но вы только что помогли мне решить мою проблему после 5 часов попыток! - person DBoyer; 12.10.2014
comment
У @DBoyer такая же проблема, как вы решили эту проблему, приведенный выше код у меня не работал. - person kokemomuke; 03.12.2015
comment
@kokemomuke Есть 2 варианта: использовать верхние/нижние колонтитулы разделов и использовать раздел с одной ячейкой для всех ваших данных (это, безусловно, самый простой вариант, если вам это сойдет с рук). Другой - это то, что предложено выше; настройка UICollectionViewFlowLayout. Я настоятельно рекомендую научиться гибко настраивать UICollectionViewFlowLayout, прежде чем пытаться добавлять дополнительные дополнительные представления самостоятельно. - person DBoyer; 04.12.2015
comment
@kokemomuke У меня есть несколько примеров, которые я написал github.com/DevonBoyer/DBMessagingKit с несколькими интересными способами. способы использования дополнительных представлений для каждой ячейки. - person DBoyer; 04.12.2015