Примечания к выпуску AppKit для OS X v10.11 предлагают что элементы представления коллекции могут быть изменены для каждого элемента:
Размер элемента может быть определен глобально для всех элементов CollectionView (путем установки свойства itemSize NSCollectionViewFlowLayout) или может варьироваться от одного элемента к другому (путем реализации -collectionView:layout:sizeForItemAtIndexPath: в вашем делегате CollectionView).
В моем случае мой CollectionViewItem состоит из одной метки, содержащей строку различной длины. Я использую NSCollectionView для отображения массива строк, поскольку NSStackViews не поддерживают привязки массивов и не переходят к новым строкам. Массив строк привязан к содержимому NSCollectionView через контроллер массива.
Файл пера моего элемента настроен правильно, корневой вид и метка имеют приоритеты Content Hugging и Content Compression Resistance, равные 1000, а края выровнены с помощью AutoLayout.
Теперь метод делегата NSCollectionViewLayout имеет эту подпись:
func collectionView(collectionView: NSCollectionView,
layout collectionViewLayout: NSCollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> NSSize
Теперь моя идея состоит в том, чтобы захватить сам элемент, запустить над ним макет, а затем вернуть новый размер элемента.
let item = collectionView.itemAtIndexPath(indexPath)!
item.view.layout()
return item.view.bounds.size
Проблема с этим подходом заключается в том, что itemAtIndexPath возвращает nil. Если я возвращаю размер по умолчанию в случае nil, этот размер по умолчанию используется для всех ячеек.
Как я могу настроить NSCollectionView для соблюдения ограничений AutoLayout моего элемента и для каждой ячейки динамически использовать вычисленный размер?
itemAtIndexPath
. Вместо этого получите содержимое из своей модели и вместо этого рассчитайте высоту. - person Harry Ng   schedule 15.01.2016nil
обратно. Представление коллекции запрашивает размер, прежде чем добавить его в представление. - person Juul   schedule 30.08.2016