swift - NSCollectionView 项间间隙指示器高度错误

标签 swift macos drag-and-drop nscollectionview nscollectionviewlayout

我正在为 macOS 实现一个应用程序,我在其中使用 NSCollectionView 作为一种时间轴。为此,我使用了 NSCollectionViewFlowLayout 的自定义子类,原因如下:

  1. 我希望项目只能水平滚动而不换行到下一行
  2. 只有 NSCollectionViewFlowLayout 似乎能够告诉 NSCollectionView 不垂直滚动(灵感来自 here)

所有这些工作都很顺利,但是:我现在正在尝试实现项目的拖放重新排序。这也有效,但我注意到项目间间隙指示器(蓝线)没有正确显示,即使我确实返回了正确的尺寸。我计算它们如下:

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 和 Collection View 中的项目数之间包括 如果我们试图在最后一个项目之后删除.如您所见,我为项目间间隙指示器返回了一个矩形,该矩形应为 3 像素宽且与项目高度相同。

虽然指示器以正确的宽度显示在正确的 x 位置,但无论我传入什么高度,它都只有 2 个像素高。

我该如何解决这个问题?

注意:如果我暂时将布局更改为 NSCollectionViewFlowLayout,指示器会正确显示。

我正在覆盖 NSCollectionViewFlowLayout 中的以下方法/属性:

  • 准备()
  • collectionViewContentSize
  • layoutAttributesForElements(in rect: NSRect) -> [NSCollectionViewLayoutAttributes]
  • layoutAttributesForItem(at indexPath: IndexPath) -> NSCollectionViewLayoutAttributes?
  • shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool
  • layoutAttributesForInterItemGap(before indexPath: IndexPath) -> NSCollectionViewLayoutAttributes?

最佳答案

您可能还需要覆盖 layoutAttributesForDropTarget(at pointInCollectionView: NSPoint) -> NSCollectionViewLayoutAttributes.

文档提到此方法返回的属性框架为间隙提供了一个边界框,将用于定位和调整放置目标指示器的大小( View )。

您可以在拖放代码中设置一个断点,在绘制放置指示器之后(例如 collectionView(:acceptDrop:indexPath:dropOperation:) 然后在拖动过程中遇到断点时-and-drop session ,运行 Xcode View 调试器以检查添加到 Collection View 后的放置指示器 View 。这样您可以确保 View 层次结构正确并且任何问题都在视觉上显而易见。

关于swift - NSCollectionView 项间间隙指示器高度错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59084562/

相关文章:

jquery - 制作可拖动的布局,可以灵活调整大小和位置

ios - 无法更改 View 中绘制的圆的颜色

swift - 以更易读的格式表示大的货币数字

ios - 从 Appstore 下载但在本地加载时不会崩溃的应用程序内购买应用程序崩溃

c - 检测 macOS 上的用户事件

android - 为什么 OS X (Yosemite) 上的 Android Studio 1.0.1 无法下载 SDK 组件?

ios - 不允许 webView 在 Swift 上播放声音

swift - SceneKit 项目用户交互

javascript - 如何使div可拖放

reactjs - 如何使用 react-testing-library 和 framer-motion 测试鼠标移动拖放