2016-11-07 81 views
3

我想从蓝色拖动条正确的行为拖动时没有蓝色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) 
    } 

} 

回答

0

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

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

我正在使用元组(String,NSColor)。元组不符合可排除协议!

从Tuples项目切换到MyClass项目后,一切工作正常! (正确的行为来自蓝色拖拽栏,拖动时不蓝色矩形)

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

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