Как перетащить элементы из NSCollectionView
Я пытаюсь реализовать перетаскивание элементов из 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 ответ
Точно так же и здесь.
Это похоже на ошибку (Xcode 9.4.1, Swit 4.1.2).
Так же, как вы упомянули, validateDrop
а также acceptDrop
позвонить в моем приложении.
Но (например), 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)
}
}
Это позволяет мне делать вещи при перетаскивании за пределы коллекции.
В этом очень простом случае просто включите / выключите выделение целевого вида:
В идеале весь этот дополнительный код не был бы необходим.
Я также ищу правильный способ справиться с этим.