【问题标题】:How to do both type of drag and drop for NSOutlineView?如何为 NSOutlineView 进行两种类型的拖放?
【发布时间】:2021-01-24 05:04:02
【问题描述】:

如何进行Finder拖放样式?

我的 ViewController 代码是这样的。

class ViewController: NSViewController {
    override func viewDidLoad() {
        outlineView.registerForDraggedTypes([.string])
        outlineView.setDraggingSourceOperationMask(.move, forLocal: true)
    }
}

拖放的代码看起来像这样。

extension ViewController: NSOutlineViewDataSource {
    func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
        guard item is SidebarRow else { return nil }
        let sidebarRowIndex = outlineView.row(forItem: item) + -1
        
        return sidebarSections[0].rows[sidebarRowIndex].name.rawValue as NSString
    }
    
    func outlineView(_ outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
        guard let outlineView = info.draggingSource as? NSOutlineView else { return [] }
        outlineView.draggingDestinationFeedbackStyle = .gap
        return .move
    }
    
    func outlineView(_ outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {
        guard item != nil else { return false }
        
        guard let items = info.draggingPasteboard.pasteboardItems,
              let pasteboardItem = items.first,
              let pasteboardItemName = pasteboardItem.string(forType: .string),
              let rowIndex = sidebarSections[0].rows.firstIndex(where: { $0.name.rawValue == pasteboardItemName }) else { return false }
        
        let new = sidebarSections[0].rows[rowIndex]
        
        sidebarSections[0].rows.remove(at: rowIndex)
        sidebarSections[0].rows.insert(new, at: index)

        outlineView.moveItem(at: rowIndex, inParent: item, to: index, inParent: item)

        return true
    }
}

我的代码并没有完全做到这一点。

同样,其他样式的拖放怎么做?

【问题讨论】:

  • 您是否尝试过设置draggingDestinationFeedbackStyleoutlineView(_:draggingSession:endedAt:operation:) 在拖动会话结束时调用 = 释放鼠标按钮时。
  • 我编辑了我的问题。我贴错了方法。它应该是outlineView(_acceptDrop:childIndex:)。结果还是一样。
  • acceptDrop 也会在释放鼠标按钮时调用。 .gapdocumentation 表示在 outlineView(_:draggingSession:willBeginAt:forItems:) 中设置样式,但 viewDidLoad 也是一个选项。 .gap 风格在我看来有点儿马虎。

标签: swift cocoa drag-and-drop appkit nsoutlineview


【解决方案1】:

感谢this answer。我的数据模型是结构。我已将侧边栏行转换为类,同时将侧边栏组保留为结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-13
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多