문제

I've subclassed NSCollectionView and I'm trying to receive dragged files from the Finder. I'm receiving draggingEntered: and returning an appropriate value, but I'm never receiving prepareForDragOperation: (nor any of the methods after that in the process). Is there something obvious I'm missing here?

Code:

- (void)awakeFromNib
{
    [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
}

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
    NSLog(@"entered"); //Happens
    NSPasteboard *pboard;
    NSDragOperation sourceDragMask;

    sourceDragMask = [sender draggingSourceOperationMask];
    pboard = [sender draggingPasteboard];

    if ([[pboard types] containsObject:NSFilenamesPboardType])
    {
        NSLog(@"copy"); //Happens
        return NSDragOperationCopy;
    }

    return NSDragOperationNone;
}

- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
    NSLog(@"prepare"); //Never happens
    return YES;
}
도움이 되었습니까?

해결책

This is pretty late, but I found the problem:

NSCollectionView silently provides an incompatible implementation of:

-(NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender

...and Apple hasn't documented this. If you simply implement that method to re-invoke the draggingEntered method, everything works fine, e.g.:

-(NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
{
    return [self draggingEntered:sender];
}

(I came to SO hoping to find an explanation of what "magic" this custom implementation provides, since that too is ... undocumented (thanks, Apple!). I'm guessing it does something clever with managing an insertion-point within the CollectionView?).

UPDATE: it seems the special magic is inside the NSCollectionView's delegate object. For some reason, Xcode4 was claiming there was no delegate for me, but assigning it built and ran OK. Check out all the custom / semi-documented drag/drop methods there.

(or just do as I describe above and override the custom behaviour, and implement something that works and you can understand)

다른 팁

You might want to try these delegate methods from the NSCollectionViewDelegate Protocol

- (NSDragOperation)collectionView:(NSCollectionView *)collectionView validateDrop:(id <NSDraggingInfo> )draggingInfo proposedIndex:(NSInteger *)proposedDropIndex dropOperation:(NSCollectionViewDropOperation *)proposedDropOperation;
- (BOOL)collectionView:(NSCollectionView *)collectionView acceptDrop:(id <NSDraggingInfo> )draggingInfo index:(NSInteger)index dropOperation:(NSCollectionViewDropOperation)dropOperation;

- (BOOL)collectionView:(NSCollectionView *)collectionView canDragItemsAtIndexes:(NSIndexSet *)indexes withEvent:(NSEvent *)event;
- (NSImage *)collectionView:(NSCollectionView *)collectionView draggingImageForItemsAtIndexes:(NSIndexSet *)indexes withEvent:(NSEvent *)event offset:(NSPointPointer)dragImageOffset;
- (NSArray *)collectionView:(NSCollectionView *)collectionView namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropURL forDraggedItemsAtIndexes:(NSIndexSet *)indexes;
- (BOOL)collectionView:(NSCollectionView *)collectionView writeItemsAtIndexes:(NSIndexSet *)indexes toPasteboard:(NSPasteboard *)pasteboard;

The first two methods in particular.

I went through this a while ago. It seemed counterintuitive to me, but the only way I could get it to work was to set up the associated scroll view as the drop target.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top