Принятие операций перетаскивания в подклассе NSCollectionView - PullRequest
4 голосов
/ 02 мая 2010

Я создал подкласс NSCollectionView и пытаюсь получить перетаскиваемые файлы из Finder. Я получаю draggingEntered: и возвращаю соответствующее значение, но я никогда не получаю prepareForDragOperation: (ни один из методов после этого в процессе). Есть ли что-то очевидное, что я здесь упускаю?

Код:

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

Ответы [ 3 ]

6 голосов
/ 03 мая 2011

Уже довольно поздно, но я нашел проблему:

NSCollectionView в режиме без вывода сообщений обеспечивает несовместимую реализацию:

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

... и Apple не задокументировала это. Если вы просто реализуете этот метод, чтобы повторно вызывать метод draggingEntered, все работает нормально, например ::

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

(Я пришел в SO, надеясь найти объяснение того, что "волшебство" обеспечивает эта пользовательская реализация, поскольку она тоже ... недокументирована (спасибо, Apple!). Я предполагаю, что она делает что-то умное с управлением вставкой точка в CollectionView?).

ОБНОВЛЕНИЕ: кажется, что специальная магия находится внутри объекта делегата NSCollectionView. По какой-то причине Xcode4 утверждал, что для меня не было делегата, но назначил его собранным и работал нормально. Проверьте все пользовательские / полу-документированные методы перетаскивания там.

(или просто сделайте, как я описал выше, и переопределите пользовательское поведение, и реализуйте то, что работает, и вы можете понять)

1 голос
/ 03 мая 2010

Возможно, вы захотите попробовать эти методы делегата из 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;

В частности, первые два метода.

0 голосов
/ 03 мая 2010

Я прошел через это некоторое время назад. Мне это показалось нелогичным, но единственный способ заставить его работать - это настроить связанный вид прокрутки в качестве цели удаления.

...