Удаление пустого места, если заголовок раздела скрыт в 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;
}
Я обнаружил, что возвращение ноль в 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. Но не повезло. тот же результат.
4 ответа
Наконец я нашел ответ на свой вопрос. Я что-то пропустил. В любом случае, извините за других пользователей.
Я установил высоту и ширину заголовка внутри метода ниже до сих пор, как сказал @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:
состояния:
Этот метод всегда должен возвращать действительный объект просмотра. Если вам не нужен дополнительный вид в конкретном случае, объект макета не должен создавать атрибуты для этого вида. Кроме того, вы можете скрыть представления, установив для скрытого свойства соответствующих атрибутов значение 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];
}
Документация ясно говорит -
Возвращаемое значение
Настроенный дополнительный вид объекта. Вы не должны возвращать ноль из этого метода.
Так что вам нужно следовать -
Этот метод всегда должен возвращать действительный объект просмотра. Если вам не нужен дополнительный вид в конкретном случае, объект макета не должен создавать атрибуты для этого вида. Кроме того, вы можете скрыть представления, установив для скрытого свойства соответствующих атрибутов значение 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;
}
}
Таким образом, вы можете скрыть / показать это