CryingHippo
CryingHippo

Reputation: 5086

NSTableRowView weird behaviour on drag and drop (keeps inserting NSView in the view hierarchy)

I've noticed strange behaviour in my app and cannot find a way to fix it: I have NSOutlineView with a custom NSTableRowView and support of drag and drop.

When I drag item(file for example) on outlineview first it draws correct hightlight (I've override drawDraggingDestinationFeedbackInRect), but on second drag I have this blue highlight and if I debug the view hierarchy I can see that NSView being added to the row.

I've attached small animation which shows exactly what happens (I've also added NSTableView with the same NSTableRowView):

Top : NSOutlineView

Bottom : NSTableView

enter image description here

View hierarchy (for the NSOutlineView):

enter image description here

Here is my code for NSTableRowView

import Cocoa

class TestRowView: NSTableRowView {

    override func drawSelectionInRect(dirtyRect: NSRect) {
        NSColor.yellowColor().setFill()
        NSBezierPath(rect: self.bounds).fill()
    }

    override func drawDraggingDestinationFeedbackInRect(dirtyRect: NSRect) {
        NSColor.greenColor().setFill()
        NSBezierPath(rect: self.bounds).fill()
    }

}

Here are datasource and delegate methods for NSOutlineView :

func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int {
    return item == nil ? allItems.count : 0
}

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

func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject {
    return allItems[index]
}

func outlineView(outlineView: NSOutlineView, viewForTableColumn tableColumn: NSTableColumn?, item: AnyObject) -> NSView? {
    return outlineView.makeViewWithIdentifier("DataCell", owner: self)
}

func outlineView(outlineView: NSOutlineView, rowViewForItem item: AnyObject) -> NSTableRowView? {
    return TestRowView()
}

func outlineView(outlineView: NSOutlineView, heightOfRowByItem item: AnyObject) -> CGFloat {
    return 60.0
}

func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? {
    return item
}

func outlineView(outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: AnyObject?, childIndex index: Int) -> Bool {
    return true
}

func outlineView(outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: AnyObject?, proposedChildIndex index: Int) -> NSDragOperation {
    return .Copy
}

What I've tried :

  1. Subclassing NSOutlineView and overriding acceptsFirstResponder

  2. Overriding backgroundStyle

  3. Tried different selectionHighlightStyle's
  4. Used NSTableViewDraggingDestinationFeedbackStyleNone

Upvotes: 1

Views: 334

Answers (1)

CryingHippo
CryingHippo

Reputation: 5086

I've found a sort of solution to my problem, here is what I've done :

First thing - subclass NSOutlineView with the following property being overriden :

override var acceptsFirstResponder: Bool{
    get{
        return false
    }
}

Secondly in my NSTableRowView subclass, I've added following :

override var selectionHighlightStyle: NSTableViewSelectionHighlightStyle {
    get{
        return self.emphasized ? .None:.Regular
    }
    set{

    }
}

I cannot say that this a good solution or even a complete solution, but better than nothing.

Sometimes I'm still getting the grey background, so I've also added a check inside setter of the override var backgroundStyle : NSBackgroundStyle property inside my NSTableCellView subclass.

Upvotes: 0

Related Questions