如何从NSCollectionView拖动项目

时间:2018-07-31 20:22:53

标签: macos drag-and-drop delegates nscollectionview nscollectionviewitem

我正在尝试从NSCollectionView中实现 的拖动项目(不仅仅是在其上放东西)。

在我的示例代码中,我通过拖动来注册CollectionView:

collectionView.registerForDraggedTypes([.URL])
collectionView.setDraggingSourceOperationMask(.every, forLocal: false)
collectionView.setDraggingSourceOperationMask(.every, forLocal: true)

然后,我已经从NSCollectionViewDelegate协议实现了这些方法:

func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {
    return true
}

func collectionView(_ collectionView: NSCollectionView, pasteboardWriterForItemAt indexPath: IndexPath) -> NSPasteboardWriting? {    
    return URL(fileURLWithPath: #file) as NSPasteboardWriting
}

func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItemsAt indexPaths: Set<IndexPath>) { }

func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, dragOperation operation: NSDragOperation) { }

但是他们两个都没有被叫过! 为什么不呢?

如果我添加这两种方法:

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

func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, indexPath: IndexPath, dropOperation: NSCollectionView.DropOperation) -> Bool {
    return true
}

然后,我可以成功地将文件从桌面拖放到集合视图中,但是反之则不能。

这是怎么回事?

最诚挚的问候,

1 个答案:

答案 0 :(得分:0)

这里完全一样。

看起来像个错误(Xcode 9.4.1,Swit 4.1.2)。

就像您提到的,validateDropacceptDrop在我的应用中被调用。
但是(例如),endedAt不会:

func collectionView(_ collectionView: NSCollectionView,
                    draggingSession session: NSDraggingSession,
                    endedAt screenPoint: NSPoint,
                    dragOperation operation: NSDragOperation) { }

(对于上面的endedAt委托,我唯一能找到的解决方法是子类NSCollectionView(在下面的示例中,我将其称为ImageCollectionView)并实现自己的{{ 1}}:

delegate/protocol

(我必须将其命名为import Cocoa protocol ImageCollectionViewDelegate { func didExitDragging() } class ImageCollectionView: NSCollectionView { var imageCollectionViewDelegate: ImageCollectionViewDelegate? } extension ImageCollectionView { override func draggingExited(_ sender: NSDraggingInfo?) { super.draggingExited(sender) imageCollectionViewDelegate?.didExitDragging() } } ,以免与已经存在的imageCollectionViewDelegate属性发生冲突。)

然后,在我的控制器(我称为delegate)中:

ImageCollectionViewController

当我将其拖到集合之外时,我可以做一些事情。
在这个非常简单的用例中,只需打开/关闭目标视图的突出显示即可:

highlighting

理想情况下,不需要所有这些额外的代码。

我也在寻找适当的方法来处理此问题。