NSCollectionView Drag and Dropping: Most Delegate Events Not Getting Called

不想你离开。 提交于 2019-12-04 06:30:15

I think you miss the part where you write the drag content to the pasteboard.
To support drag and drop you have to perform the following steps:

  1. Determine if you can drag in your drag source
  2. If YES, write the content to the Pasteboard
  3. Validate & accept the items in your drop target

Writing to the Pasteboard should be implemented in
- collectionView:writeItemsAtIndexes:toPasteboard:

You also have to register your dragged types with - registerForDraggedTypes:

Some sample code: http://developer.apple.com/library/mac/#samplecode/IconCollection/Introduction/Intro.html

This code has everything I needed to drag an image from one NSCollectionView to another. Figuring this out was NOT super obvious. Selectable is checked for the source collection view and wired up for the dataSource and delegate outlets, but I did not need registerForDraggedTypes.

class Window:NSWindow, NSComboBoxDelegate, NSTextFieldDelegate, NSDatePickerCellDelegate, NSTableViewDataSource, NSTableViewDelegate, MKMapViewDelegate, NSCollectionViewDataSource, NSCollectionViewDelegate, NSCollectionViewDelegateFlowLayout, NSTabViewDelegate, NSMenuDelegate, NSDraggingDestination { }

    func collectionView(collectionView: NSCollectionView, writeItemsAtIndexPaths indexPaths: Set<NSIndexPath>, toPasteboard pasteboard: NSPasteboard) -> Bool {
    let index = indexPaths.first!.item
    let url = webImageURLs[index]   // array of string URLs that parallels the collection view.
    NSPasteboard.generalPasteboard().clearContents()
    NSPasteboard.generalPasteboard().declareTypes([kUTTypeText as String, kUTTypeData as String], owner: nil)
    NSPasteboard.generalPasteboard().setString(url, forType: (kUTTypeText as String))
    NSPasteboard.generalPasteboard().setData(webImageData[index], forType: (kUTTypeData as String))
    return true
}

// Provide small version of image being dragged to accompany mouse cursor.
func collectionView(collectionView: NSCollectionView, draggingImageForItemsAtIndexPaths indexPaths: Set<NSIndexPath>, withEvent event: NSEvent, offset dragImageOffset: NSPointPointer) -> NSImage {
    let item = collectionView.itemAtIndex(indexPaths.first!.item)
    return (item?.imageView?.image)!.resizeImage(20, height: 20)
}

// Image is dropped on destination NSCollectionView.
func collectionView(collectionView: NSCollectionView, draggingSession session: NSDraggingSession, endedAtPoint screenPoint: NSPoint, dragOperation operation: NSDragOperation) {
    let pasteboardItem = NSPasteboard.generalPasteboard().pasteboardItems![0]
    let urlString = pasteboardItem.stringForType((kUTTypeText as String))
    let imageData = pasteboardItem.dataForType((kUTTypeData as String))

    // destinationImages is the data source for the destination collectionView. destinationImageURLs is used to keep track of the text urls.
    if urlString != nil {
        destinationImageURLs.insert(urlString!, atIndex: 0)
        destinationImages.insert(NSImage(data: imageData!)!, atIndex: 0)
        destinationCollectionView.reloadData()
        let selectionRect = self.favoritesCollectionView.frameForItemAtIndex(0)
        destinationCollectionView.scrollRectToVisible(selectionRect)
    }
}

extension NSImage {
    func resizeImage(width: CGFloat, height: CGFloat) -> NSImage {
        let img = NSImage(size: CGSizeMake(width, height))
        img.lockFocus()
        let ctx = NSGraphicsContext.currentContext()
        ctx?.imageInterpolation = .High
        drawInRect(NSRect(x: 0, y: 0, width: width, height: height), fromRect: NSRect(x: 0, y: 0, width: size.width, height: size.height), operation: .CompositeCopy, fraction: 1)
        img.unlockFocus()

        return img
    }
} 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!