Я ищу лучший способ использовать автоматическую компоновку для расчета размера дополнительных представлений в пользовательском файле 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
, и он не позволит мне удалить дополнительное представление из очереди, пока не появятся атрибуты макета хотя бы для одной ячейки.
Я подумал о следующем:
- Я мог бы сначала разместить ячейки, а затем заголовок. Однако это усложняет логику установки рамок ячеек, поскольку они зависят от высоты заголовка.
- Я мог бы создать «фиктивные» атрибуты для ячейки, создать и изменить размер заголовка, а затем обновить атрибуты-фиктивы при компоновке первой реальной ячейки. Это не сложно, но и не очень чисто!
- Я мог бы вручную создать экземпляр
ACVHeaderView
, чтобы использовать его для определения размера заголовков. Это сработало бы, но в моем реальном случае у меня есть несколько дополнительных представлений. Кажется неаккуратным вести собственный учет дополнительных видов и повторно использовать идентификаторы, а также словарь представлений-прототипов. Я бы дублировал логику, используемую в механизме удаления из очереди представления коллекции.
Каков наилучший способ добиться этого? Я полагаю, что должен упустить что-то более простое, потому что Apple поощряет разработчиков правильно использовать динамический тип и авто-макет.