Question

I have two columns in my NSOutlineView. One is a Text and image cell (similar to the class in the DragNDropOutlineView Apple sample code). Next to that is a custom NSCell subclass called "XFToggleCell" that is used to display a visibility icon (eyeball) that you can toggle on and off (just like Photoshop).

The XFToggleCell supports mouse tracking/dragging (again, just like Photoshop) so you can click one eyeball, then drag down to show/hide multiple items at once. In the text and image cell, I display the text in gray when the item's hidden, and black when it's not.

Almost everything is working fine. When I click an eyeball (XFToggleCell), it's image clears out and my model object becomes hidden. However, the adjacent text and image cell's font doesn't become gray (it doesn't update) until I click the toggle cell again...and when I do, the coloring of the image and text cell's text is always opposite of what it should be (when the visibility is clicked on, the text goes gray, and vice versa).

I determined that the reason this is happening is because the text and image cell is being redrawn before the value of the toggle cell is changed. As a result, its display is always "one click behind". The sequence goes like this:

  1. I mousedown on column 1's toggle cell.
  2. The text and image cell in column 0 is redrawn.
  3. The object value for the toggle cell in column 1 is changed.
  4. The toggle cell in column 1 is redrawn.

If I can force a redraw of the text and image cell in column 0 as step 5 above, I should be good to go.

How do I force an update to the drawing of column 0's text and image cell as a result of clicking on column 1's cell?

Here's the implementation of what I think is the key method...In my XFToggleCell.m, which is in column 1:

- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView
{
    .
    .
    .
    ...do some stuff...
    .
    .
    .
    //Here's where I change the cell's object value, causing the cell to be redrawn.
    //This part works fine.
    [self setObjectValue:([self.representedObject newState]) ? self.image : nil];
    .
    .
    .
    //Why doesn't this next line update the adjacent cell?!?!?!?!?
    //Column 0 contains the text and image cell I'm trying to update
    [controlView setNeedsDisplayInRect:[(NSOutlineView *)controlView frameOfCellAtColumn:0 row:thisRow]];
    }
    return YES;
}
Was it helpful?

Solution

Well, I'm not quite sure why, but calling

[(NSOutlineView *)controlView setNeedsDisplayInRect:[(NSOutlineView *)controlView frameOfCellAtColumn:col row:row]];

didn't work when I put it at the end of

-(BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView

in my XFToggleCell class.

So I tried adding

[outlineView setNeedsDisplayInRect:[outlineView frameOfCellAtColumn:col row:row]];

at the end of my

-(void) outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item

method in my NSOutlineView datasource and it worked. Not sure why, but this is how to do it. If anyone can shed light as to why it didn't work calling essentially the same thing in the cell, I'd appreciate the info.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top