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

StackOverflow https://stackoverflow.com//questions/20042900

Вопрос

У меня есть два раздела в 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: сбой метода и для других тоже.Другие ответы, предлагающие удалить этот метод.

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

РЕДАКТИРОВАТЬ:

Как сказал @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.Но безуспешно.тот же результат.

Это было полезно?

Решение

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

До сих пор я устанавливал высоту и ширину заголовка внутри приведенного ниже метода, как сказал @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);
    }
}

ОБНОВЛЕНИЕ: Поскольку кто-то усомнился в моем мастерстве в комментариях, прикрепляю Apple Ссылка на документацию для возврата CGSizeZero в приведенном выше методе.

Другие советы

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

Этот метод всегда должен возвращать допустимый объект представления.Если вам не нужен дополнительный вид в конкретном случае, ваш объект макета не должен создавать атрибуты для этого вида.В качестве альтернативы вы можете скрыть представления, установив для свойства hidden соответствующих атрибутов значение 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];
}

В документации четко сказано -

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

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

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

Этот метод всегда должен возвращать допустимый объект представления.Если вам не нужен дополнительный вид в конкретном случае, ваш объект макета не должен создавать атрибуты для этого вида.В качестве альтернативы вы можете скрыть представления, установив для свойства hidden соответствующих атрибутов значение 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;
}

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

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)
        }
    }

Вы можете скрыть / показать свой повторно используемый раздел заголовка, добавив 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;
}
}

Так что вы можете скрыть / показать это

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top