нет экземпляра UICollectionViewLayoutAttributes для -layoutAttributesForSupplementaryElementOfKind:

Заголовок - это ошибка, которую я получаю, и я понятия не имею, почему, но вот некоторая информация, так что, надеюсь, кто-то здесь сможет мне объяснить.

Я создал подкласс UICollectionViewFlowLayout, так как это избавляет меня от расчета кадров для ячейки (возможно, это проблема?) в prepareLayout. Затем я использую информацию UICollectionViewLayoutAttributes для расчета дополнительного вида, который накладывается на него, и получаю желаемый макет.

Я использую performBatchUpdates:completion: для добавления, удаления и обновления представления. Вставка работает нормально, однако при удалении элементов появляется ошибка, указанная в заголовке.

Итак, я знаю, почему возникает ошибка, но я не знаю, почему это вообще должно происходить. Чтобы пояснить на примере сценария, вызывающего проблему

  1. Начните с 1 элемента с 1 дополнительным видом 1 раздел
  2. Добавьте еще два элемента (prepareLayout видит 3 элемента с 3 дополнительными представлениями)
  3. Удалить элемент (prepareLayout видит 2 представления с 2 дополнительными представлениями)
  4. layoutAttributesForSupplementaryViewOfKind:atIndexPath: вызывается с запросом атрибутов для пути индекса с section:0 и item:2
  5. Сбой, потому что он запросил атрибуты для третьего дополнительного представления, хотя ранее он вызывал подготовку макета, устанавливая 2 элемента и 2 дополнительных представления.
  6. Бросьте руки вверх в смирении и отчаянии

поэтому оскорбительная функция, насколько я могу судить, такова:

- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
{
    return self.layoutInfo[elementKind][indexPath];
}

который, конечно, автоматически вызывается внутренней сетью UICollectionView, поэтому я понятия не имею, почему он запрашивает это дополнительное представление по этому индексному пути.

У кого-нибудь есть идеи? Возможно, именно так я использую performBatchUpdates:completion:, но удаление работало нормально, пока не были добавлены дополнительные представления. При необходимости я могу предоставить больше кода/объяснений.




Ответы (2)


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

Несколько недель спустя из любопытства я снова огляделся и в конце концов наткнулся на следующий пост и теперь я снова вернулся к использованию дополнительных представлений.

Итак, не забудьте вернуть свой:

- (NSArray<NSIndexPath *> *)indexPathsToDeleteForSupplementaryViewOfKind:(NSString *)elementKind
{
    return self.removedIndexPaths;
}

к вашему макету просмотра коллекции.

person Genhain    schedule 10.07.2016
comment
@ micromanc3r Это слова человека, который столкнулся с проблемой, не имея ни малейшего понятия, почему она не работает, безрезультатно пробуя случайные вещи в течение нескольких дней подряд. Рад, что смог помочь положить конец страданиям. - person Genhain; 04.08.2017

Чтобы предотвратить сбой, вы можете вернуть фиктивные атрибуты для всех тех indexPath, которые больше не действительны. Что-то вроде этого может помочь предотвратить сбой:

UICollectionViewLayoutAttributes *layoutAttributes = self.layoutInfo[elementKind][indexPath]; // add some safety checks if this access creates an out of bounds issue

// create dummy layoutAttributes
// the workaround
if (layoutAttributes == nil) {
    UICollectionViewLayoutAttributes *dummyLayoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:elementKind withIndexPath:indexPath];
    dummyLayoutAttributes.frame = CGRectZero;
    dummyLayoutAttributes.hidden = YES;
    layoutAttributes = dummyLayoutAttributes;
}

return layoutAttributes;

Это по-прежнему приводит к объектам в вашем стеке представления, которых там быть не должно, но они скрыты и не вызывают сбоя. В следующий раз, когда UICollectionView обновит свой макет, он должен очистить старые скрытые представления.

person Stefan Arn    schedule 10.07.2016
comment
откуда вы получаете self.layoutInfo? - person Sweta Vani; 26.04.2021