NSCollectionView с элементами динамической ширины с использованием автоматического макета
Я создаю элемент, который прокручивается по горизонтали с элементами, которые выглядят примерно так:
У меня есть элемент, определенный в .xib с автоматическими ограничениями макета. Ширина элемента определяется шириной метки плюс ширина метки счетчика (и окружающей ее таблетки). Все это заключено в
NSView
под названием «Коробка».
Вот ограничения для Box:
У меня подключен источник данных, и все выглядит нормально, за исключением того, что я не могу изменить ширину элемента в зависимости от размеров представлений внутри него.
Из того, что я прочитал, я не могу полагаться исключительно на автоматическую компоновку для определения размера здесь (надеюсь, я ошибаюсь в этом) так же, как если бы я использовал динамическую высоту в
NSTableView
. Поэтому я пытаюсь рассчитать размер с помощью
sizeForItemAt
делегировать метод из
NSCollectionViewDelegateFlowLayout
:
func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "PhaseItem"), for: indexPath) as! PhaseItem
return item.box.fittingSize
}
Когда я печатаю
fittingSize
для консоли это выглядит правильно. Но я получаю
Unable to simultaneously satisfy constraints
сбой, связанный с размером Box (у него есть подкласс
RoundedWrap
):
"<NSLayoutConstraint:0x6000033c3890 H:|-(11)-[NSTextField:0x7ff6abf6e9f0] (active, names: '|':Avid.RoundedWrap:0x7ff6abf74840 )>",
"<NSLayoutConstraint:0x6000033c6300 H:[NSTextField:0x7ff6abf6e9f0]-(7)-[Avid.BadgeView:0x7ff6abf6f120] (active)>",
"<NSLayoutConstraint:0x6000033c5400 H:[Avid.BadgeView:0x7ff6abf6f120]-(9)-| (active, names: '|':Avid.RoundedWrap:0x7ff6abf74840 )>",
"<NSLayoutConstraint:0x6000033c39d0 H:|-(8)-[NSTextField:0x7ff6abf6f360] (active, names: '|':Avid.BadgeView:0x7ff6abf6f120 )>",
"<NSLayoutConstraint:0x6000033c2760 H:[NSTextField:0x7ff6abf6f360]-(8)-| (active, names: '|':Avid.BadgeView:0x7ff6abf6f120 )>",
"<NSLayoutConstraint:0x6000033c3a20 H:|-(0)-[Avid.RoundedWrap:0x7ff6abf74840] (active, names: '|':NSView:0x7ff6abf74a80 )>",
"<NSLayoutConstraint:0x6000033c3b60 H:[Avid.RoundedWrap:0x7ff6abf74840]-(0)-| (active, names: '|':NSView:0x7ff6abf74a80 )>",
"<NSAutoresizingMaskLayoutConstraint:0x6000033140f0 h=--& v=--& NSView:0x7ff6abf74a80.width == 0 (active)>"
Сбой исчезнет, если я удалю ограничение, которое прикрепляет задний край Box к содержащему представлению, но тогда мой
NSCollectionView
элементы вообще не появляются.
Есть ли более простой способ сделать все это? Как я могу использовать автоматическую компоновку для установки динамической ширины моего
NSCollectionViewItem
с?
1 ответ
Похоже, я был на правильном пути. Мне просто нужно было добавить:
item.view.layoutSubtreeIfNeeded()
Как это
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
///...
item.view.layoutSubtreeIfNeeded()
return item
}
Для того, чтобы размер элемента был точным.