Подтвердить что ты не робот

Удаление пустого пространства, если заголовок раздела скрыт в UICollectionView

У меня два раздела в UICollectionView. Я хочу показать заголовок раздела в UICollectionView только для 1-го раздела. Не в 0-й секции.

Итак, я попытался вернуть nil в viewForSupplementaryElementOfKind: метод для section == 0 и возвращает вид для section == 1.

Он выходит из строя и отображается ниже ошибки:

Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes]:

Вот мой код для дополнительного вида.

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader && indexPath.section == 1) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];
        sectionHeader.layer.borderWidth = .5f;
        sectionHeader.layer.borderColor = [UIColor colorWithRed:221.0 / 255.0 green:223.0 / 255.0 blue:220.0 / 255.0 alpha:1.0].CGColor;
    }

    return sectionHeader;
}

Я обнаружил, что возвращение nil в viewForSupplementaryElementOfKind: метод сбой для других тоже. Другие ответы, предлагающие удалить этот метод.

Но я хочу показать заголовок раздела только для определенных разделов. Как достичь этого возвращающегося представления только для одного раздела? Благодарю. Любая помощь будет оценена.

EDIT:

Как сказал @san, я обновил код, чтобы скрыть заголовок раздела. Оно работает. Он скрывает заголовок. Но я все еще вижу пустое место вместо заголовка секции. Ожидаемые результаты не должны быть места для заголовка раздела, если он скрыт.

обновленный код:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{

    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];
        sectionHeader.layer.borderWidth = .5f;
        sectionHeader.layer.borderColor = [UIColor colorWithRed:221.0 / 255.0 green:223.0 / 255.0 blue:220.0 / 255.0 alpha:1.0].CGColor;
        if (indexPath.section == 0) {
            sectionHeader.hidden = YES;

        }else {
            sectionHeader.hidden = NO;
        }
    }

    return sectionHeader;
}

Я даже попытался установить фрейм для sectionHeader как @san. Но не повезло. тот же результат.

4b9b3361

Ответ 1

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

Я устанавливаю высоту и ширину заголовка внутри метода ниже до сих пор как @san сказал.

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath

Но это неправильный метод для установки размера кадра дополнительных видов. Позже я нашел другой метод внутри flowLayout, который помогает мне устанавливать размеры заголовка и нижнего колонтитула.

Это действительно хорошо работает для меня:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return CGSizeZero;
    }else {
        return CGSizeMake(CGRectGetWidth(collectionView.bounds), 135);
    }
}

UPDATE: Поскольку кто-то задал вопрос о моем навыке в комментариях, добавьте Apple Ссылка документации для возврата CGSizeZero в вышеуказанный метод.

Ответ 2

В документации для collectionView:viewForSupplementaryElementOfKind:atIndexPath: указано:

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

Учитывая, что вы уже пытались установить высоту на ноль и установить скрытое представление, вы должны подклассифицировать UICollectionViewFlowLayout и реализовать layoutAttributesForSupplementaryViewOfKind:atIndexPath:

Проверьте indexPath (как вы уже это сделали) и верните nil, если вам не нужны атрибуты макета для этого конкретного дополнительного вида.

- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    if([indexPath section] == 0)
    {
         return nil;
    }

    return [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
}

Ответ 3

Документация четко говорит -

Возвращаемое значение

Конфигурированный дополнительный объект вида. Вы не должны возвращать нуль из этого метода.

Итак, вам нужно следовать -

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

Следуя вашему коду, ниже фрагмент должен работать для вас:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];

        if(indexPath.section == 1)
          {
             sectionHeader.layer.borderWidth = .5f;
             sectionHeader.layer.borderColor = [UIColor colorWithRed:221.0 / 255.0 green:223.0 / 255.0 blue:220.0 / 255.0 alpha:1.0].CGColor;
          }
        else
        {
          sectionHeader.frame = CGRectZero;
          sectionHeader.hidden = YES;
        }
    }

    return sectionHeader;
}

Ответ 4

В моем случае я дал вставку разделам, чтобы она давала мне пустое место. Так что, если вы реализовали следующий метод, сделайте это ниже

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        if <condition for which you want to hide section>{
            return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        }else{
            return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        }
    }

Ответ 5

Вы можете скрыть/показать раздел заголовка повторно используемого файла, добавив делегат UICollectionViewDelegateFlowLayout и используя ниже код

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
if (self.isForSearch) { //---> for hiding
    return CGSizeMake(0,0);
}
else{//---> for showing
    return ((UICollectionViewFlowLayout*)self.collectionChoosePlanView.collectionViewLayout).headerReferenceSize;
}
}

Итак, вы можете скрыть/показать его