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
}

Для того, чтобы размер элемента был точным.

Другие вопросы по тегам