Pregunta

Tengo un NSCollectionView vinculado a un nsArrayController. Quiero que funcionen con arrastre y caída, por lo que creo un delegado e implemento los métodos.

-(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

Estoy devolviendo sí para los dos métodos bool, nsdragOperationMove para el método ValidatedRop: y una matriz vacía para los nombres de los nombres de la prueba de droppedTestination: método. También tengo una declaración de NSLOG como la primera línea en cada método para que pueda ver cuándo se les llama.

En este momento, el único método que se llama es CandragitemsatIndexes: (donde devuelvo sí). Veo que se llama, pero cualquier arrastre adicional solo modifica la selección. El resto nunca se llama.

Si hago que NSCollectionView no admite selecciones, entonces ni siquiera se llama ese método.

Estoy seguro de que me estoy perdiendo algo súper obvio, pero no puedo entender qué es. ¿Alguien se ha arrastrado y deja trabajar con NSCollectionViews y puede arrojar algo de luz?

¿Fue útil?

Solución

Creo que te pierdes la parte en la que escribes el contenido de arrastre al cartón.
Para admitir arrastrar y soltar, debe realizar los siguientes pasos:

  1. Determine si puede arrastrar su fuente de arrastre
  2. Si YES, escriba el contenido en el cartón
  3. Validar y aceptar los elementos en su objetivo de caída

Escribir en el cartón debe implementarse en
- collectionView:writeItemsAtIndexes:toPasteboard:

También debe registrar sus tipos arrastrados con - registerForDraggedTypes:

Algún código de muestra:http://developer.apple.com/library/mac/#samplecode/iconcollection/introduction/intro.html

Otros consejos

Este código tiene todo lo que necesitaba para arrastrar una imagen de un NSCollectionView a otro. Supongo que esto no era súper obvio. Selectable se verifica para la vista de la colección de origen y se conecte para los puntos de venta de DataSource y Delegate, pero no necesitaba 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
    }
} 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top