Индикатор межэлементного разрыва NSCollectionView имеет неправильную высоту
Я реализую приложение для macOS, в котором использую NSCollectionView
как своего рода временная шкала. Для этого я использую собственный подклассNSCollectionViewFlowLayout
по следующим причинам:
- Я хочу, чтобы элементы можно было прокручивать только по горизонтали без переноса на следующую строку
- Только
NSCollectionViewFlowLayout
кажется способным сказатьNSCollectionView
не прокручивать по вертикали (вдохновение отсюда)
Все это работает плавно, однако: я сейчас пытаюсь реализовать перетаскивание и падение переназначения из пунктов. Это тоже работает, но я заметил, что индикатор промежутка между элементами (синяя линия) не отображается должным образом, хотя я возвращаю правильные размеры. Я их рассчитываю следующим образом:
override func layoutAttributesForInterItemGap(before indexPath: IndexPath) -> NSCollectionViewLayoutAttributes?
{
var result: NSCollectionViewLayoutAttributes? = nil
// The itemLayoutAttributes dictionary is created in prepare() and contains
// the layout attributes for every item in the collection view
if indexPath.item < itemLayoutAttributes.count
{
if let itemLayout = itemLayoutAttributes[indexPath]
{
result = NSCollectionViewLayoutAttributes(forInterItemGapBefore: indexPath)
result?.frame = NSRect(x: itemLayout.frame.origin.x - 4, y: itemLayout.frame.origin.y, width: 3, height: itemLayout.size.height)
}
}
else
{
if let itemLayout = itemLayoutAttributes.reversed().first
{
result = NSCollectionViewLayoutAttributes(forInterItemGapBefore: indexPath)
result?.frame = NSRect(x: itemLayout.value.frame.origin.x + itemLayout.value.frame.size.width + 4, y: itemLayout.value.frame.origin.y, width: 3, height: itemLayout.value.size.height)
}
}
return result
}
Согласно документации indexPath
передаваемый в метод, может быть от 0 до количества элементов в представлении коллекции, в том числе, если мы пытаемся отбросить после последнего элемента. Как видите, я возвращаю прямоугольник для индикатора промежутка между элементами, который должен иметь ширину 3 пикселя и такую же высоту, как и элемент.
Хотя индикатор отображается в правильном x-положении с правильной шириной, его высота составляет всего 2 пикселя, независимо от того, какую высоту я ввожу.
Как это исправить?
NB: Если я временно изменю макет на NSCollectionViewFlowLayout
индикатор отображается правильно.
Я отменяю следующие методы / свойства в NSCollectionViewFlowLayout
:
- подготовить()
- collectionViewContentSize
- layoutAttributesForElements(in rect: NSRect) -> [NSCollectionViewLayoutAttributes]
- layoutAttributesForItem (в indexPath: IndexPath) -> NSCollectionViewLayoutAttributes?
- shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool
- layoutAttributesForInterItemGap(перед indexPath: IndexPath) -> NSCollectionViewLayoutAttributes?
1 ответ
Вам также может потребоваться переопределитьlayoutAttributesForDropTarget(at pointInCollectionView: NSPoint) -> NSCollectionViewLayoutAttributes
.
В документации упоминается, что фрейм атрибутов, возвращаемых этим методом provides a bounding box for the gap, that will be used to position and size a drop target indicator
(Посмотреть).
Вы можете установить точку останова в своем коде перетаскивания после того, как отобразится индикатор перетаскивания (например, collectionView(:acceptDrop:indexPath:dropOperation:)
а затем, когда точка останова будет достигнута во время сеанса перетаскивания, запустите отладчик представления Xcode, чтобы проверить представление индикатора перетаскивания после его добавления в представление коллекции. Таким образом, вы можете быть уверены, что иерархия представлений верна и любые проблемы визуально очевидны.