3

Я реализовал липкие заголовки разделов для просмотра коллекции, используя http://blog.radi.ws/post/32905838158/sticky-headers-for-uicollectionview-using в качестве прыгающей точки, и они работают.Ошибка с UICollectionView и пользовательский раскладной формат

Но я вижу очень странный крах.

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

UICollectionView received layout attributes for a cell with an index path that does not exist 

Вот поток выполнения:

по мнению редактора подробно, я изменить название элемента, таким образом, что он будет двигаться из раздела X в раздел Y.

Модель объекта выдает уведомление об изменении имени.

Контроллер корневого представления, которому принадлежит представление коллекции, улавливает уведомление «имя изменено», перестраивает его внутренние индексы, а затем вызывает -reloadData в представлении коллекции. Это все хорошо.

Я нажал на кнопку Назад в пользовательском интерфейсе, и следующий поток происходит (подтвержден с помощью отладчика и пещерный NSLog вызовов)

  • numberOfSectionsInCollectionView: называется, и мой код возвращает правильное количество секций
  • CollectionView : numberOfItemsInSection: вызывается для каждого раздела, и возвращается правильное количество элементов.
  • Вызывается мой пользовательский макет потока -layoutAttributesForElementsInRect:. Первое, что я делаю, - вызвать [super layoutAttributesForElementsInRect], чтобы получить базовый макет.

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

Теперь вот что наводит мой разум.

Если я прокомментирую всю реализацию -layoutAttributesForElementsInRect, она по-прежнему падает. Но если я прокомментирую:

- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBound { 
    return YES; 
} 

Тогда он работает правильно.

Это говорит о том, что вид коллекции, или что-то в макете потока является кэширование результатов, но только если макет потока shouldInvalidateLayoutForBoundsChange

Примечание, если я просто использовать ваниль UICollectionViewFlowLayout все работает отлично.

TLDR

Пользовательские UICollectionViewFlowLayout, если -shouldInvalidateLayoutForBoundsChange возвращает YES, получает устарелый раскладка атрибутов из [супер layoutAttributesForElementsInRect]

Любые идеи?

+0

Убедитесь, что вы сохраняете атрибуты layoutAttributes для каждого типа элементов в соответствии с соответствующим индексом в отдельных словарях в методе prepareLayout. Вернуть тот же самый макет атрибута для соответствующего индекса из соответствующих словарей элементов. –

+1

Вы поняли это? Я думаю, что у меня почти такая же проблема. –

+0

Я «исправил» это, но в хакерской манере. В конце концов, у меня была заметка о моей коллекции, если она была/скрыта/когда были внесены изменения, и отложить вызов для перезагрузки данных в этой ситуации для просмотраDidAppear: – TomorrowPlusX

ответ

0

Я решил эту проблему путем удаления shouldInvalidateLayoutForBoundsChange: переопределения, и вместо реализации scrollViewDidScroll: на делегате Представления коллекции, чтобы аннулировать макет:

override func scrollViewDidScroll(scrollView: UIScrollView) { 
    collectionView?.collectionViewLayout.invalidateLayout() 
} 

Это держит липкие заголовки, но останавливает сбои.

+4

У этого есть серьезные проблемы с производительностью – Ranjit

+0

☝️ Согласовано. очень плохо на производительность –

+1

Я уверен, что альтернативное решение будет приветствоваться. –

Смежные вопросы