Пример для перетаскивания внутри NSCollectionView

Я хотел бы переместить предметы внутри NSCollectionView используя его методы делегирования перетаскивания. Я работаю до тех пор, пока предмет не упадет. Индикатор назначения (пробел) отсутствует, и при отпускании мыши элемент отскакивает назад. Делегаты validateDrop а также acceptDrop никогда не звонят. CollectionViewItems показывают данные из пользовательских объектов:

введите описание изображения здесь

func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {

    print("canDragItem", indexPaths)
    return true
}

func collectionView(_ collectionView: NSCollectionView, writeItemsAt indexPaths: Set<IndexPath>, to pasteboard: NSPasteboard) -> Bool {

    let indexData = Data(NSKeyedArchiver.archivedData(withRootObject: indexPaths))
    pasteboard.declareTypes(["my_drag_type_id"], owner: self)
    pasteboard.setData(indexData, forType: "my_drag_type_id")

    print("write data", indexData)
    return true
}


func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndex proposedDropIndex: UnsafeMutablePointer<Int>, dropOperation proposedDropOperation: UnsafeMutablePointer<NSCollectionViewDropOperation>) -> NSDragOperation {

    print("validation")
    return NSDragOperation.move
}

func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, index: Int, dropOperation: NSCollectionViewDropOperation) -> Bool {

    let pb = NSPasteboard()
    let indexData = (pb.data(forType: "my_drag_type_id"))! as Data
    let indexPath = (NSKeyedUnarchiver.unarchiveObject(with: indexData)) as! IndexPath
    let draggedCell = indexPath.item as Int

    print("acceptDrop", draggedCell)


    return true
}

Какого черта... Я думаю, что что-то не так с записью данных об элементе, которые нужно перетащить в монтажный картон. Какие-либо предложения.

1 ответ

Есть две возможные причины этой проблемы. В этом конкретном случае ответ Виллека является правильным. На самом деле вы все еще можете использовать старые версии indexSet всех функций делегирования с перетаскиванием, но если вы это сделаете, вы должны убедиться, что все они являются старыми версиями, не смешивая старые и новые!

Короче говоря, если ваш canDragItems: Функция делегата имеет параметр с именем indexPaths, а затем убедитесь, что writeItemsAt:, validateDrop: а также acceptDrop: функции также используют IndexPaths, а не IndexSets.

Во-вторых, и это имело место в моем случае, убедитесь, что вы запомнили регистрацию для типов перетаскивания, которые вы хотите, чтобы представление вашей коллекции отвечало где-то разумному, т.е. viewDidLoad - см. фрагмент кода ниже - и, конечно, тот же тип перетаскивания устанавливается в монтажном столе при создании данных перетаскивания в первую очередь!

collectionView.register(forDraggedTypes: [dragType])
Другие вопросы по тегам