Принятие операций перетаскивания в подкласс NSCOLECTECTERVIEW
-
02-10-2019 - |
Вопрос
У меня подкласс NSCOLECTECTERVIEW, и я пытаюсь получить перетаскиваемые файлы от 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;
}
Решение
Это довольно поздно, но я нашел проблему:
NscollectionView молча предоставляет несовместимую реализацию:
-(NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
... и Apple не задокументировала это. Если вы просто реализуете этот метод для повторного введения метода DraggingEdered, все работает нормально, например:
-(NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
{
return [self draggingEntered:sender];
}
(Я пришел к тому, что я надеялся найти объяснение того, что обеспечивает «магия» эта пользовательская реализация, так как это тоже ... без документов (спасибо, Apple!). Я предполагаю, что она делает что-то умное с управлением точкой вставки внутри CollectionView?).
ОБНОВЛЕНИЕ: Кажется, особая магия находится внутри объекта делегата NSCollectionView. По какой -то причине XCODE4 утверждал, что для меня не было делегата, но присвоение его построенным и работало ОК. Проверьте все пользовательские / полудокументированные методы перетаскивания / выпадения там.
(или просто делайте, как я описываю выше, и переопределяйте пользовательское поведение, и реализуйте что -то, что работает, и вы можете понять)
Другие советы
Вы можете попробовать эти методы делегатов из 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;
В частности, первые два метода.
Я прошел через это некоторое время назад. Это казалось нелогичным для меня, но единственный способ, которым я мог заставить его работать, - это установить соответствующий вид свитка в качестве цели падения.