2016-11-07 2 views
3

Je voudrais un comportement correct dans la barre de glisser bleu , et pas rect bleu lors du déplacement.NSOutlineView dragline collé + bordure bleue

Savez-vous où est mon erreur?

(comme vous pouvez le voir, la barre bleue est coincé en haut, comme dans ce sujet: 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) 
    } 

} 

Répondre

0

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

Chaque élément la vue en plan doit être unique. Pour que l'état replié reste cohérent entre les rechargements, le pointeur de l'élément doit rester le même et l'élément doit conserver isEqual (_ :) identité.

J'utilisais Tuples (String, NSColor). Et les tuples ne se conforment pas au protocole hashable! Après le passage d'éléments de Tuples à des éléments MyClass, tout fonctionne bien! (comportement correct de la barre de défilement bleue et pas de rectangle bleu lors du déplacement)

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

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