Размер дополнительных представлений с автоматическим макетом в пользовательском UICollectionViewLayout

Я ищу лучший способ использовать автоматическую компоновку для расчета размера дополнительных представлений в пользовательском файле UICollectionViewLayout. Для ясности это упрощенное объяснение того, чего я пытаюсь достичь.

У меня есть дополнительный вид заголовка ACVHeaderView с ограничениями автоматического макета.

В prepareLayout: я хочу рассчитать размер заголовка раздела и создать для него дополнительные атрибуты макета представления. Затем я хочу перебрать ячейки в этом разделе, создавая и сохраняя атрибуты макета для ячеек. После «построения» макета все эти атрибуты будут сохранены для возврата другими методами макета представления коллекции.

В идеале я хочу изменить размер заголовка, вызвав collectionView:dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:, выполнить проход автоматического макета, а затем использовать view:systemLayoutSizeFittingSize:. Это именно то, что я делаю для самих ячеек (следуя некоторому примеру кода, который я получил от WWDC).

Однако это не удается с этой ошибкой:

2014-09-04 18:51:53.852 ACV[7298:167827] *** Assertion failure in -[UICollectionViewData layoutAttributesForSupplementaryElementOfKind:atIndexPath:], /SourceCache/UIKit_Sim/UIKit-3302.3.1/UICollectionViewData.m:853
2014-09-04 18:51:53.916 ACV[7298:167827] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for layout attributes for supplementary view UICollectionElementKindSectionHeader in section 0 when there are only 0 sections in the collection view'

Я понимаю проблему, я думаю... Я пытаюсь исключить из очереди дополнительное представление для заголовка, прежде чем я изменю размер ячеек в этом разделе. Это означает, что я еще не создал никаких атрибутов макета для каких-либо ячеек в этом разделе (используя UICollectionViewLayoutAttributes.forCellWithIndexPath:). UICollectionViewData выглядит как внутренний класс, который отслеживает атрибуты макета в UICollectionView, и он не позволит мне удалить дополнительное представление из очереди, пока не появятся атрибуты макета хотя бы для одной ячейки.

Я подумал о следующем:

  1. Я мог бы сначала разместить ячейки, а затем заголовок. Однако это усложняет логику установки рамок ячеек, поскольку они зависят от высоты заголовка.
  2. Я мог бы создать «фиктивные» атрибуты для ячейки, создать и изменить размер заголовка, а затем обновить атрибуты-фиктивы при компоновке первой реальной ячейки. Это не сложно, но и не очень чисто!
  3. Я мог бы вручную создать экземпляр ACVHeaderView, чтобы использовать его для определения размера заголовков. Это сработало бы, но в моем реальном случае у меня есть несколько дополнительных представлений. Кажется неаккуратным вести собственный учет дополнительных видов и повторно использовать идентификаторы, а также словарь представлений-прототипов. Я бы дублировал логику, используемую в механизме удаления из очереди представления коллекции.

Каков наилучший способ добиться этого? Я полагаю, что должен упустить что-то более простое, потому что Apple поощряет разработчиков правильно использовать динамический тип и авто-макет.




Ответы (1)


Возможно иметь раздел с 0 ячейками в разделе, так что это не должно вызывать эту проблему. Я думаю, проблема в том, что вы добавили дополнительные атрибуты заголовка, но раздел недоступен (numberOfSectionsInCollectionView возвращает 0).

Я хотел бы убедиться, что numberOfSectionsInCollectionView: не не возвращает 0, когда вы добавляете дополнительные атрибуты заголовка.

person lsw    schedule 08.09.2014
comment
Спасибо @EllisWeng. numberOfSectionsInCOllectionView определенно возвращал правильный номер. Как оказалось, это начало работать в Xcode 6 GM, так что похоже, что это была ошибка. Спасибо за вашу помощь. - person AndrewC; 11.09.2014