I've subclassed NSOutlineView
and implemented NSSpringLoadingDestination
, but springLoadingActivated()
is only ever called on non-leaf rows, even though I've implemented springLoadingEntered()
and springLoadingUpdated()
to indiscriminately return [.enabled]
. I assume NSOutlineView
's built-in drag & drop support is interfering with my attempts. Is there a workaround for this?
Feels a little hacky, but it seems I can get away with this by spring loading the rows, but also overriding all of the NSDraggingDestination
methods to pass the word on to the parent NSOutlineView
:
class SpringLoadedOutlineRow: NSTableCellView, NSSpringLoadingDestination {
var outlineView: NSOutlineView! {
didSet {
registerForDraggedTypes(outlineView.registeredDraggedTypes)
}
}
//Pass through `NSDraggingDestination` methods so we don't interfere with `NSOutlineView`
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
return outlineView.draggingEntered(sender)
}
override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool {
return outlineView.prepareForDragOperation(sender)
}
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
return outlineView.performDragOperation(sender)
}
override func concludeDragOperation(_ sender: NSDraggingInfo?) {
outlineView.concludeDragOperation(sender)
}
override func draggingExited(_ sender: NSDraggingInfo?) {
outlineView.draggingExited(sender)
}
//Only pass through if we're expandable & not yet expanded (to get `NSOutlineView`'s default disclosure spring-loading); otherwise it will eat our leaf spring-loading
override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
guard let representedItem = outlineView.item(atRow: outlineView.row(for: self)) else { return outlineView.draggingUpdated(sender) }
if outlineView.isExpandable(representedItem) && !outlineView.isItemExpanded(representedItem) {
return outlineView.draggingUpdated(sender)
} else {
return []
}
}
//Actually spring-load!
func springLoadingActivated(_ activated: Bool, draggingInfo: NSDraggingInfo) {
//Whatever you want
}
func springLoadingHighlightChanged(_ draggingInfo: NSDraggingInfo) {
}
func springLoadingEntered(_ draggingInfo: NSDraggingInfo) -> NSSpringLoadingOptions {
return [.enabled]
}
func springLoadingUpdated(_ draggingInfo: NSDraggingInfo) -> NSSpringLoadingOptions {
return [.enabled]
}
}