Местоположение верхнего и нижнего колонтитула iOS UICollectionView

Работая в iOS 7, как указать, куда помещаются поля верхнего и нижнего колонтитула в UICollectionView?

У меня есть пользовательский UICollectionViewFlowLayout. я перезаписал

-(void)prepareLayout

-(NSArray*) layoutAttributesForElementsInRect:(CGRect)rect

-(UICollectionViewLayoutAttributes*) layoutAttributesForSupplementaryViewOfKind: (NSString*)kind atIndexPath:(NSIndexPath*)indexPath

Моя проблема в том, что я не уверен, как указать местоположение заголовка. Я уже указал, что заголовок существует в prepareLayout:

-(void)prepareLayout
{
[super prepareLayout];

boundsSize = self.collectionView.bounds.size;
midX = boundsSize.width / 2.0f;
curIndex = 0;

self.headerReferenceSize = CGSizeMake(CELL_SIZE, TITLE_HEIGHT);
self.footerReferenceSize = CGSizeMake(0, 0);

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(TOP_INSET, LEFT_INSET, BOTTOM_INSET, RIGHT_INSET);
self.minimumLineSpacing = LINE_SPACING;
self.minimumInteritemSpacing = INTERIM_SPACING;
self.itemSize = CGSizeMake(CELL_SIZE, CELL_SIZE);

}

Я просто не знаю, какое свойство моего пользовательского FlowLayout нужно установить, поскольку, похоже, не существует чего-то вроде «HeaderLocation» для установки ни в качестве LayoutAttributes, ни в самом объекте макета. Прямо сейчас он появляется сбоку/между моими изображениями, когда я хочу, чтобы они появлялись над каждым изображением (горизонтальная прокрутка).

Я пробовал следующее:

-(UICollectionReusableView*) collectionView: (UICollectionView*)collectionView viewForSupplementaryElementOfKind:(NSString*)kind atIndexPath:(NSIndexPath*)indexPath
{
    NSLog(@"**ViewForSupplementaryElementOfKind called***");

    CGFloat centerX = collectionView.center.x;
    CGFloat centerY = collectionView.center.y;
    CGFloat titleWidth = [MyLayout titleWidth];
    CGFloat titleHeight = [MyLayout titleHeight];

    MyTitleView* titleView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:ImageTitleIdentifier forIndexPath:indexPath];

    titleView.frame = CGRectMake(centerX - titleWidth/2.0,
                                 0.0,
                                 titleWidth,
                                 titleHeight);

    return titleView;
}

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

PS> Пожалуйста, не предлагайте ничего, что связано с размещением NIB или XIB. Я использую UICollectionView, а НЕ UICollectionViewController, поэтому на самом деле у меня нет прототипа ячейки для работы. Макет создается полностью программно — только из кода — поэтому я не могу просто открыть файл XIB и настроить расположение текстового поля.


person Erika Electra    schedule 16.05.2014    source источник


Ответы (2)


Изменение атрибутов, возвращаемых -layoutAttributesForElementsInRect, является правильным подходом, но если вы хотите изменить положение закадровых верхних и нижних колонтитулов, вам может потребоваться самостоятельно получить дополнительные атрибуты представления.

Например, в вашем подклассе UICollectionViewFlowLayout:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *attributesArray = [[super layoutAttributesForElementsInRect:rect] mutableCopy];

    // the call to super only returns attributes for headers that are in the bounds,
    // so locate attributes for out of bounds headers and include them in the array
    NSMutableIndexSet *omittedSections = [NSMutableIndexSet indexSet];
    for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
        if (attributes.representedElementCategory == UICollectionElementCategoryCell) {
            [omittedSections addIndex:attributes.indexPath.section];
        }
    }
    for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
        if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
            [omittedSections removeIndex:attributes.indexPath.section];
        }
    }
    [omittedSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
        UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                                                                            atIndexPath:indexPath];
        [attributesArray addObject:attributes];
    }];

    for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
        if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {

            // adjust any aspect of each header's attributes here, including frame or zIndex

        }
    }

    return attributesArray;
}
person followben    schedule 16.05.2014
comment
Спасибо за публикацию такого количества кода, но не могли бы вы указать, какой атрибут вы редактируете? Это самая важная часть. Вы написали: «//настройте любой аспект атрибутов каждого заголовка здесь, включая фрейм или zIndex», но меняет ли редактирование фрейма место размещения заголовка? Он просто перекрывает уже существующий контент? Что такое конкретный атрибут? (Их много, и я не вижу ни одного в документации с названием «headerLocation», «headerOrigin», «headerFrame» или что-то в этом роде) - person Erika Electra; 17.05.2014
comment
... редактирование фрейма там меняет место размещения шапки? Он просто перекрывает уже существующий контент? Но это именно то, что делают свойства frame и zIndex UICollectionViewLayoutAttribute. Могу я мягко предложить вам сначала прочитать документы? - person followben; 17.05.2014
comment
Вы также можете найти эту статью полезной для более глубокого понимания UICollectionViewLayoutAttributes и как они работают. - person followben; 17.05.2014
comment
Спасибо. Конечно, я уже прочитал документы; они говорят Например, представления верхнего и нижнего колонтитула выложены иначе, чем ячейки, и могут быть предоставлены для отдельных разделов или для представления коллекции в целом. но они никогда не говорят, как изменить расположение этих верхних и нижних колонтитулов. У меня тот же вопрос, что и раньше: как называется свойство, которое определяет их местоположение? Пока не ответишь, все остальное не имеет значения. - person Erika Electra; 17.05.2014
comment
Это не то, как работают представления коллекций. Вы не устанавливаете положение верхнего или нижнего колонтитула напрямую; вместо этого вы устанавливаете свойства центра или фрейма в соответствующем экземпляре UICollectionViewLayoutAttributes, возвращаемом макетом. zIndex определяет, находится ли он выше или ниже остального вашего контента. - person followben; 18.05.2014

Высота заголовка CollectionView установлена ​​ниже делегата Collectionview.

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section

И установите представление в заголовке Collectionview в нижнем делегате

- (UICollectionReusableView*)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView * view = nil;

    if ([kind isEqualToString:UICollectionElementKindSectionHeader])
    {
        ColorSectionHeaderView *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                                                            withReuseIdentifier:NSStringFromClass([ColorSectionHeaderView class])
                                                                                   forIndexPath:indexPath];
        header.sectionIndex = indexPath.section;
        header.hideDelete = collectionView.numberOfSections == 1; // hide when only one section
        header.delegate = self;
        view = header;
    }

return view;

}

Класс Ragistred в ViewDidLoad

-(void)ViewDidLoad
{

[collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([ColorSectionFooterView class]) bundle:nil]
     forSupplementaryViewOfKind:UICollectionElementKindSectionFooter
            withReuseIdentifier:NSStringFromClass([ColorSectionFooterView class])];

   [Super ViewDidLoad];
}
person Kirit Modi    schedule 16.05.2014
comment
Спасибо, но я уже знаю, как изменить высоту, я хочу знать, где изменить МЕСТО. Например, я хочу сказать программе, чтобы мой заголовок отображался НАД содержимым с координатой y = 0. Где в вашем решении вы явно указываете, что заголовок должен быть размещен в определенном месте? dequeueReusableSupplementaryView не дает мне контроля над этим. - person Erika Electra; 16.05.2014
comment
Что такое MyTitleView? Является ли класс? - person Kirit Modi; 16.05.2014
comment
Да, это мой класс заголовка. - person Erika Electra; 16.05.2014
comment
Вы рагицред Класс во viewDidLoad Как выше редактирую' - person Kirit Modi; 16.05.2014
comment
Кирит Моди, я ценю ваш ответ, но, как я уже сказал, вы не ответили, как изменить местоположение. - person Erika Electra; 17.05.2014