简体   繁体   中英

Use first column for drag image in NSTableView

I'm implementing drag and drop in a table view, and the problem I'm having is that the drag image is always based on the column where the drag started, but I want to use the image from the first column.

I looked at Apple's TableViewPlayground sample, where the "Complex OutlineView Window" does what I want, but I can't figure out what I'm doing different in terms of setting up the drag.

I put together a simple example at https://github.com/Uncommon/TableTest - if you drag from the second column where it says "stuff", then it looks like you're dragging the word "stuff". What I want is to have the drag image always come from the first column (with the icon and name) regardless of which column you drag from.

In my data source I implement tableView(tableView:,pasteboardWriterForRow:) to enable dragging, but that doesn't include information about what column the drag started in. What am I missing from the example app to make this work?

NSTableView drags the column where the drag started, NSOutlineView drags the outline column. If you want to change the image, subclass NSTableView and override dragImageForRows(with:tableColumns:event:offset:) .

The accepted answer didn't work for me. Instead, I had to implement the following optional function in NSTableViewDataSource :

func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) {
        // Or whatever cell you want as the drag image
        let cell = tableView.view(atColumn: 0, row: rowIndexes.first!, makeIfNecessary: false) as? NSTableCellView
        session.enumerateDraggingItems(options: .concurrent, for: nil, classes: [NSPasteboardItem.self], searchOptions: [:]) {(draggingItem, idx, stop) in
            if let cell = cell {
                let rect = cell.bounds
                let drag = session.draggingLocation
                // You can customize the image starting point and size here
                draggingItem.setDraggingFrame(NSRect(x: drag.x, y: drag.y, width: rect.width, height: rect.height), contents: cell.draggingImageComponents)
                draggingItem.imageComponentsProvider = {
                    return cell.draggingImageComponents
                }
            }
        }
    }

Credit goes to this answer for providing much of this solution.

In response to why dragImageForRows(with:tableColumns:event:offset:) didn't work:

From the Apple documentation :

Note : To support multi-item drags, it is highly recommended to implement the delegate method tableView:pasteboardWriterForRow: instead. Using that method will cause this method to not be called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM