NSCollectionViewItem 中的附加视图暂停 CollectionViewController 中的 dragEvent

Additional view in NSCollectionViewItem pauses dragEvent in CollectionViewController

我正在尝试在 NSCollectionViewController 上实现放置委托,但在使用自定义 NSCollectionViewItem 以及我添加到 CollectionView 项目的附加视图层时遇到问题。 FWIW,附加视图用于绘制虚线边框以指示放置区域。

拖动事件在这个 collectionItem 和所有其他没有这个视图的 collectionItem 上工作正常,当它被隐藏时,但是一旦拖动事件发生在这个视图之上,拖动事件就会暂停。

鼠标被拖出视图后,拖动事件会立即恢复,但如果我在鼠标悬停在视图上方时释放拖动,则不会发生任何事情。

我很想知道这里发生了什么,以及如何防止自定义视图受到 "stealing" 来自 CollectionViewContoller 的鼠标事件的影响。

DropViewController 上的委托方法

    func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndexPath proposedDropIndexPath: AutoreleasingUnsafeMutablePointer<NSIndexPath>, dropOperation proposedDropOperation: UnsafeMutablePointer<NSCollectionView.DropOperation>) -> NSDragOperation {
        print("1")


        if proposedDropIndexPath.pointee.item <= self.destinationDirectoryArray.count {
            if proposedDropOperation.pointee == NSCollectionView.DropOperation.on {
                return .move
            }
        } else if proposedDropIndexPath.pointee.item == self.destinationDirectoryArray.count {
            //There's some stuff here validating the URL removed for brevity. It works okay when the focus is outside the view, but happy to add back in if helpful

            if proposedDropOperation.pointee == NSCollectionView.DropOperation.on {
                return .move
            }
        }
        return[]
    }

配置集合视图

func configureCollectionView() {
    let flowLayout = NSCollectionViewFlowLayout()
    flowLayout.minimumInteritemSpacing = 8.0
    flowLayout.minimumLineSpacing = 8.0

    destinationCollectionView.delegate = self
    destinationCollectionView.dataSource = self
    destinationCollectionView.register(NSNib(nibNamed: "DestinationCollectionItem", bundle: nil), forItemWithIdentifier: directoryItemIdentifier)
    destinationCollectionView.collectionViewLayout = flowLayout
    destinationCollectionView.registerForDraggedTypes([.fileURL])
    destinationCollectionView.setDraggingSourceOperationMask(NSDragOperation.move, forLocal: true)
}

集合视图项目设置

    class DestinationCollectionItem: NSCollectionViewItem {

        @IBOutlet weak var backgroundLayer: NSView!


        override func viewDidLoad() {
            super.viewDidLoad()
            self.highlightState = .none
            view.wantsLayer = true
            view.layer?.cornerRadius = 8.0
            backgroundLayer.isHidden = true
        } 

}

自定义边框视图 - 在 Xib 中应用自定义 class 并链接到文件所有者

class BorderedView: NSView {

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        let path : NSBezierPath = NSBezierPath(roundedRect: self.bounds, xRadius: 10.0, yRadius: 10.0)
        path.addClip()

        let dashHeight: CGFloat = 2
        let dashLength: CGFloat = 7
        let dashColor: NSColor = .lightGray

        // setup the context
        let currentContext = NSGraphicsContext.current!.cgContext
        currentContext.setLineWidth(dashHeight)
        currentContext.setLineDash(phase: 0, lengths: [dashLength])
        currentContext.setStrokeColor(dashColor.cgColor)

        // draw the dashed path
        let cgPath : CGPath = CGPath(roundedRect: NSRectToCGRect(self.bounds), cornerWidth: 10.0, cornerHeight: 10.0, transform: nil)
        currentContext.addPath(cgPath)
        currentContext.strokePath()
    }

}

嗯 - 我很快就解决了这个问题。

虽然我之前尝试将 unregisterDraggedTypes() 添加到 backgroundLayer,但事实证明问题也出现在图像层上。我将它应用于 Image 和 backgroundLayer,现在可以使用了。

集合视图项目设置

class DestinationCollectionItem: NSCollectionViewItem {

    @IBOutlet weak var backgroundLayer: NSView!


    override func viewDidLoad() {
        super.viewDidLoad()
        self.highlightState = .none
        view.wantsLayer = true
        view.layer?.cornerRadius = 8.0
        backgroundLayer.isHidden = true
        backgroundLayer.unregisterDraggedTypes()
        self.imageView?.unregisterDraggedTypes()
        self.textField?.unregisterDraggedTypes()
    }

}