【问题标题】:How to drag items from NSCollectionView如何从 NSCollectionView 中拖动项目
【发布时间】:2019-01-08 07:54:13
【问题描述】:

我正在尝试实现从 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
}

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

发生了什么事?

最好的问候,V。

【问题讨论】:

  • 收藏视图的“可选择”是否开启?
  • @Willeke:我刚刚再次尝试将isSelectable 设置为falsetrue,它似乎根本没有任何区别。 :(

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


【解决方案1】:

这里完全一样。

看起来是一个错误?(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)并实现我自己的 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):

@IBOutlet internal weak var imageCollectionView: ImageCollectionView! {
    didSet {
        imageCollectionView.imageCollectionViewDelegate = self
    }
}

extension ImageCollectionViewController: ImageCollectionViewDelegate {
    func didExitDragging() {
        highlightDestination(false)
    }
}

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

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

我也在寻找处理这个问题的正确方法。 ??

【讨论】:

    猜你喜欢
    • 2018-07-23
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    相关资源
    最近更新 更多