Представления, совместимые с заголовком UICollectionView

Я построил UICollectionView в раскадровке и реализовал все необходимые методы источника данных и делегата в контроллере представления. В раскадровке я проверил свойство Section Header в представлении коллекции и установил класс представления заголовка в подкласс UICollectionResusableView (в раскадровке).

Отсюда я перетащил два элемента пользовательского интерфейса в представление заголовка через раскадровку — метку и сегментированный элемент управления:

введите здесь описание изображения

Когда программа выполняется, метка появляется в представлении заголовка представления коллекции (фактический код не требуется), а сегментированный элемент управления — нет. Однако когда сегментированный элемент управления перетаскивается на типичный UIView, он отображается и им можно манипулировать без необходимости кода. Даже при создании экземпляра с помощью кода в IBOutlet сегментированный элемент управления не отображается.

Почему сегментированный элемент управления не отображается в заголовке представления коллекции, когда он находится в типичном UIView, и почему метка отображается без проблем?

ОБНОВЛЕНИЕ

Вот метод инициализации пользовательского представления заголовка, в котором я попытался программно добавить сегментированный элемент управления (в отличие от раскадровки):

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"One", @"Two", nil]];
        [_segmentedControl setFrame:CGRectMake(0, 0, 100, 50)];
        [_segmentedControl addTarget:self action:@selector(segmentedControlChanged:) forControlEvents:UIControlEventValueChanged];
        [self addSubview:_segmentedControl];
    }
    return self;
}

Как и просили, вот метод -[UICollectionReusableView viewForSupplementaryElementOfKind:] в контроллере основного представления:

- (UICollectionReusableView *)collectionView:(UICollectionView *)cv viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    GalleryHeader *headerView = [cv dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
    return headerView;
}

person The Kraken    schedule 14.06.2013    source источник
comment
Вы реализовали метод uicollectionviewdatasource collectionView:viewForSupplementaryElementOfKind:atIndexPath:?   -  person micantox    schedule 18.06.2013
comment
Да. Я отправлю код для этого тоже.   -  person The Kraken    schedule 18.06.2013
comment
Хорошо, тогда подожду редактирования   -  person micantox    schedule 18.06.2013


Ответы (1)


Я не могу воспроизвести вашу проблему с раскадровкой, она отлично работает для меня, когда я добавляю сегментированный элемент управления, перетаскивая его прямо в раскадровку (без кода). Что касается вашего альтернативного способа добавления его программно, проблема здесь в том, что когда представление инициализируется из раскадровки (как в этом случае), используется метод инициализатора initWithCoder (а не метод инициализатора initWithFrame). Следовательно, если вы переопределите этот метод, вставив туда код, он должен работать:

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if(self){
        _segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"One", @"Two", nil]];
        _segmentedControl.bounds = CGRectMake(0, 0, 100, 50);
        [_segmentedControl addTarget:self action:@selector(segmentedControlChanged:) forControlEvents:UIControlEventValueChanged];
        [self addSubview:_segmentedControl];
    }
    return self;
}

P.S. Это не влияет на этот конкретный случай, но вы должны просто сделать:

GalleryHeader *headerView = [cv dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];

вместо:

GalleryHeader *headerView = [cv dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];

Поскольку именно представление коллекции будет запрашивать правильный вид представления, вам следует побеспокоиться об его указании!

РЕДАКТИРОВАТЬ: Шаги, которые я выполнил, чтобы создать заголовок из раскадровки:

  • Выберите представление коллекции и установите флажок Заголовок раздела.

  • Выберите только что созданный заголовок и выберите правильный класс в инспекторе идентификации.

введите здесь описание изображения

  • Дайте разделу заголовка уникальный идентификатор

введите здесь описание изображения

  • Перетащите элементы пользовательского интерфейса в заголовок в раскадровке (я также изменил цвет фона)

введите здесь описание изображения

  • Наконец, реализуйте метод collectionView:viewForSupplementaryElementOfKind:atIndexPath: в классе источника данных вашего представления коллекции.
 -(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
          viewForSupplementaryElementOfKind:(NSString *)kind 
                                atIndexPath:(NSIndexPath *)indexPath
 {
     return [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"collectionViewHeader" forIndexPath:indexPath];
 }

Дайте мне знать, если вы заметите разницу между тем, что вы сделали, и тем, что сделал я!

person micantox    schedule 18.06.2013
comment
Спасибо за ответ. Я понимаю проблему initWithFrame: и вместо этого использовал метод initWithCoder:, но безрезультатно. Вы упомянули, что не смогли воспроизвести проблему с раскадровкой. Возможно, вы могли бы прислать мне тестовый проект, который вы сделали, чтобы я мог сравнить их бок о бок. - person The Kraken; 18.06.2013
comment
Боюсь, было бы не так просто поделиться всем проектом, так как у меня есть некоторые рабочие материалы, которыми я не могу поделиться! В любом случае, подождите секунду, как вы определяете _segmentedControl? Это выход? - person micantox; 18.06.2013
comment
Это простое свойство в заголовочном файле: @property (nonatomic, strong) UISegmentedControl *segmentedControl;, так что нет, это не розетка. - person The Kraken; 18.06.2013
comment
Не могли бы вы поделиться своим проектом? - person micantox; 18.06.2013
comment
Извините, конфиденциальные вещи и с моей стороны тоже. - person The Kraken; 18.06.2013
comment
Хорошо, я отредактирую свой вопрос и шаг за шагом пройдусь по тому, что я сделал, может быть, вы заметите разницу с тем, что сделали вы. - person micantox; 18.06.2013
comment
Спасибо за редактирование; Я очень ценю ваше время. Теперь я получаю сообщение об ошибке: 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindSectionHeader with identifier facade - must register a nib or a class for the identifier or connect a prototype cell in a storyboard' - person The Kraken; 18.06.2013
comment
Разве мне не нужно создавать экземпляр GalleryView в методе -viewForSupplementaryElementOfKind:? - person The Kraken; 18.06.2013
comment
нет, просто измените идентификатор (который я просто указал как фасад) на тот, который вы на самом деле указали в своей раскадровке! В моем примере я должен был поместить его как collectionViewHeader (теперь я снова отредактировал свой ответ!). Вам не нужно на самом деле создавать его экземпляр, так как метод удаления из очереди сделает это за вас! - person micantox; 18.06.2013
comment
И снова метка отображается, а сегментированный элемент управления — нет. - person The Kraken; 18.06.2013
comment
Если бы я мог воспроизвести проблему, я мог бы помочь, но это просто показывает для меня! Попробуйте поместить следующий код в свой метод initWithFramer и дайте мне знать, что получится на выходе: self = [super initWithCoder:aDecoder]; for( UIView *view in self.subviews ) NSLog(@"%@", [view class]); return self; - person micantox; 18.06.2013
comment
Конечно же, он указывает UISegmentedControl как подпредставление. Может тогда проблема только в отображении? - person The Kraken; 18.06.2013
comment
Я предполагаю, что вы используете авторазметку, и причиной всего этого является какое-то хитрое ограничение! - person micantox; 18.06.2013
comment
просто попробуйте отключить авторазметку, чтобы подтвердить это - person micantox; 18.06.2013
comment
Авторазметка отключена, никакого эффекта. Но элемент управления определенно добавляется как подвид. - person The Kraken; 18.06.2013
comment
Гоша, это становится довольно расстраивающим. Хотел бы я просто взяться за этот проект! - person micantox; 18.06.2013
comment
Я думаю, что, возможно, заметил проблему. Существует раскрывающееся меню «Просмотреть как», которое позволяет мне просматривать проект с точки зрения iOS 7 или iOS 6. Когда я нажал на iOS 7, сегментированный элемент управления исчез. Это похоже на проблему. Дай мне минутку, чтобы подтвердить. - person The Kraken; 18.06.2013
comment
Да, это явно был источник проблемы — похоже на трюк iOS 7. Большое спасибо за всю вашу помощь и за то, что привели меня к правильному ответу. 50 баллов вам. - person The Kraken; 18.06.2013
comment
Благодаря вам, это был довольно скучный день раньше :) - person micantox; 18.06.2013