Перетаскивание NSCollectionView: большинство событий делегата не вызывается - PullRequest
6 голосов
/ 29 апреля 2011

У меня есть NSCollectionView, связанный с NSArrayController.Я хочу, чтобы перетаскивание работало, поэтому я создаю делегат и реализую методы

-(BOOL)collectionView:(NSCollectionView *)collectionView canDragItemsAtIndexes:(NSIndexSet *)indexes withEvent:(NSEvent*)event
-(BOOL)collectionView:(NSCollectionView *)collectionView acceptDrop:(id < NSDraggingInfo >)draggingInfo index:(NSInteger)index dropOperation:(NSCollectionViewDropOperation)dropOperation
-(NSDragOperation)collectionView:(NSCollectionView *)collectionView validateDrop:(id < NSDraggingInfo >)draggingInfo proposedIndex:(NSInteger *)proposedDropIndex dropOperation:(NSCollectionViewDropOperation *)proposedDropOperation
-(NSArray *)collectionView:(NSCollectionView *)collectionView namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropURL forDraggedItemsAtIndexes:(NSIndexSet *)indexes

Я возвращаю YES для двух методов BOOL, NSDragOperationMove для метода validateDrop: и пустой массив дляnamesOfPromisedFilesDroppedAtDestination: метод.У меня также есть оператор NSLog в качестве первой строки в каждом методе, чтобы я мог видеть, когда они будут вызваны.

Прямо сейчас единственный вызываемый метод - canDragItemsAtIndexes: (где я возвращаю YES).Я вижу, что он вызывается, но любое дальнейшее перетаскивание просто изменяет выделение.Остальным никогда не позвонят.

Если я заставлю NSCollectionView не поддерживать выборки, то даже этот метод не будет вызван.

Я уверен, что упускаю что-то супер очевидное, но я не могу понять, что это такое.Кто-нибудь получил перетащить и работать с NSCollectionViews и может пролить свет?

Ответы [ 2 ]

4 голосов
/ 29 апреля 2011

Я думаю, что вам не хватает той части, где вы записываете содержимое для перетаскивания в монтажную область.
Чтобы поддерживать перетаскивание, вам необходимо выполнить следующие шаги:

  1. Определить, можно ли перетаскиватьВаш источник перетаскивания
  2. Если YES, запишите содержимое в Картон
  3. Проверьте и примите элементы в вашей цели перетаскивания

Запись в Картон должна бытьреализовано в
- collectionView:writeItemsAtIndexes:toPasteboard:

Вы также должны зарегистрировать перетаскиваемые типы с помощью - registerForDraggedTypes:

Некоторые примеры кода: http://developer.apple.com/library/mac/#samplecode/IconCollection/Introduction/Intro.html

0 голосов
/ 27 января 2016

В этом коде есть все, что мне нужно для перетаскивания изображения из одного NSCollectionView в другой. Выяснить это не было супер очевидно. Выбираемый проверяется для представления коллекции источника и подключается для выходных данных dataSource и делегата, но мне не нужно 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
    }
} 
...