macosnscollectionviewnscollectionviewitem

Cannot drag onto image in NSCollectionViewItem


I am designing a folder browser application similar to Finder. I want to enable users to drag files from outside the application and drop them onto a folder within my application, causing the dragged items to be added into that folder.

My custom NSCollectionViewItem object, ArchiveCollectionViewItem, consists of a single NSImageView and a NSTextField. The image view is connected to the ArchiveCollectionViewItem's imageView outlet and the text field is connected to the textField outlet.

In collectionView:itemForRepresentedObjectAtIndexPath:, I find an item that corresponds to the NSCollectionViewItem and display it:

- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
{
    if (collectionView == self.collectionView && 0 == indexPath.section)
    {
        NSCollectionViewItem *item =
                [collectionView makeItemWithIdentifier:@"ArchiveCollectionViewItem" forIndexPath:indexPath];
        if (item && [item isKindOfClass:[ArchiveCollectionViewItem class]])
        {
            ArchiveCollectionViewItem *archiveCollectionViewItem = (ArchiveCollectionViewItem *) item;
            ArchiveItemViewModel *archiveItem = [self archiveItemAtIndexPath:indexPath];
            archiveCollectionViewItem.archiveItemViewModel = archiveItem;

            return archiveCollectionViewItem;
        }
        else
        {
            return item;
        }
    }
    else
    {
        return nil;
    }
}

ArchiveCollectionViewItem's setArchiveItemViewModel method is as follows:

- (void)setArchiveItemViewModel:(ArchiveItemViewModel *)archiveItemViewModel
{
    _archiveItemViewModel = archiveItemViewModel;
    NSString *itemName = archiveItemViewModel.name;
    NSImage *itemImage = archiveItemViewModel.isFolder ?
            [NSImage imageNamed:NSImageNameFolder] :
            [[NSWorkspace sharedWorkspace] iconForFileType:itemName.pathExtension.lowercaseString];
    self.imageView.image = itemImage;
    self.textField.stringValue = itemName;
}

Everything works as intended, except when items are dragged onto the ArchiveCollectionViewItem's image. When I drag an item onto the non-image portion of my ArchiveCollectionViewItem, I get the green plus sign indicating a valid drop:

valid drop

However, when I drag the item onto the image portion, the green plus sign disappears. In addition, collectionView:validateDrop:proposedIndexPath:dropOperation: does not get called:

invalid drop

What should I do to get the entire ArchiveCollectionViewItem view to accept the drop? Or is this not possible / not allowed?

Most other NSCollectionView drag and drop questions focus on dragging and dropping within the application (to rearrange) or from inside the application to outside of it. To be clear, neither of those are my use cases. I haven't been able to find another SO question similar to mine (thus far), so if one exists, please accept my apologies and link me to it.


Solution

  • Even when an image view is uneditable it apparently still handles drag & drop. To fix this call the image view's unregisterDraggedTypes method.

    Same problem: NSOutlineView spring loading exits over NSImageView but not NSButton.