NSOutlineView拖动线卡住+蓝色边框

时间:2016-11-07 18:08:06

标签: swift cocoa nsoutlineview

我喜欢蓝色拖动条中的正确行为,拖动时无蓝色矩形

你知道我的错误在哪里吗?

(正如您所看到的,蓝色栏位于顶部,如本主题所示:  Little circle-line bar stuck at top of NSOutlineView when rearranging using drag and drop

bug

import Cocoa

class ViewController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate, NSPasteboardItemDataProvider {

    @IBOutlet weak var outlineView: NSOutlineView!

    let REORDER_PASTEBOARD_TYPE = "com.test.calques.item"

    override func viewDidLoad() {
        super.viewDidLoad()

        //Register for the dropped object types we can accept.
        outlineView.register(forDraggedTypes: [REORDER_PASTEBOARD_TYPE])

        //Disable dragging items from our view to other applications.
        outlineView.setDraggingSourceOperationMask(NSDragOperation(), forLocal: false)

        //Enable dragging items within and into our view.
        outlineView.setDraggingSourceOperationMask(NSDragOperation.every, forLocal: true)

        outlineView.delegate = self;
        outlineView.dataSource = self;
    }

    override var representedObject: Any? {
        didSet {
            // Update the view, if already loaded.
        }
    }

    var items: [(String, NSColor)] = [
        ("Item 1",  NSColor.black),
        ("Item 2",  NSColor.red),
        ("Item 3",  NSColor.red),
        ("Item 4",  NSColor.red),
        ("Item 5",  NSColor.red),
        ("Item 6",  NSColor.red)];

    //NSOutlineViewDataSource
    func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
        return items.count;
    }

    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
        return false
    }

    func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
        return items[index];
    }

    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
        let image: NSImage = NSImage(size: NSSize(width: 17, height: 17));
        let calquesItem: (String, NSColor) = item as! (String, NSColor);
        let path = NSBezierPath(ovalIn: CGRect(x: 2, y: 2, width: 17 - 4, height: 17 - 4));

        image.lockFocus();
        calquesItem.1.setFill();
        path.fill();
        image.unlockFocus();

        let cell = outlineView.make(withIdentifier: "DataCell", owner: nil) as! NSTableCellView;
        cell.textField!.stringValue = calquesItem.0;
        cell.imageView!.image = image;

        return cell;
    }

    //Drag - NSOutlineViewDataSource
    var fromIndex: Int? = nil;

    func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
        let pastBoardItem: NSPasteboardItem = NSPasteboardItem();

        pastBoardItem.setDataProvider(self, forTypes: [REORDER_PASTEBOARD_TYPE]);

        return pastBoardItem;
    }

    func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItems draggedItems: [Any]) {

        Swift.print("willBeginAt")

        let item = draggedItems[0] as! (String, NSColor);

        fromIndex = items.index(where: { (_item: (String, NSColor)) -> Bool in
            return _item.0 == item.0
        });

        session.draggingPasteboard.setData(Data(), forType: REORDER_PASTEBOARD_TYPE)
    }

    func outlineView(_ outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {
        Swift.print("acceptDrop")

        if(fromIndex! != index && index != -1) {
            let toIndex: Int = fromIndex! < index ? index - 1 : index;

            outlineView.moveItem(at: fromIndex!, inParent: nil, to: toIndex, inParent: nil);

            items.insert(items.remove(at: fromIndex!), at: toIndex);

            return true;
        }

        return false;
    }

    func outlineView(_ outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
        if(item == nil) {
            return NSDragOperation.generic;
        }

        return [];
    }

    func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
        Swift.print("Drag session ended")
        fromIndex = nil;
    }

    //NSPasteboardItemDataProvider
    func pasteboard(_ pasteboard: NSPasteboard?, item: NSPasteboardItem, provideDataForType type: String)
    {
        item.setString("Outline Pasteboard Item", forType: type)
    }

}

1 个答案:

答案 0 :(得分:0)

来自https://developer.apple.com/reference/appkit/nsoutlineview

  

大纲视图中的每个项目都必须是唯一的。为了   折叠状态以在重新加载项目之间保持一致   指针必须保持不变,并且项必须保持isEqual(_ :)   同一性。

我正在使用Tuples(String,NSColor)。而且元组不符合可以使用的协议!

从Tuples项目切换到MyClass项目后,一切正常! (蓝色拖动条的正确行为,拖动时没有蓝色矩形)

class MyClass {
    var name: String!
    var color: NSColor!

    init(_ _name: String, _ _color: NSColor) {
        name = _name
        color = _color
    }
}