custom table row selection highlights - my bug or Apple's?


James Walker
 

I have a view-based NSTableView in a scroll view. I want to customized the way that selection highlighting is drawn. So, I set up a controller as a delegate of the table, and in the delegate method tableView:rowViewForRow: I provide an instance of a subclass of NSTableRowView, call it NameRowView. NameRowView overrides one method:

- (void) drawBackgroundInRect: (NSRect) dirtyRect
{
NSLog(@"drawBackgroundInRect %@", self);
if (self.selected)
{
[NSColor.greenColor setFill];
}
else
{
[NSColor.yellowColor setFill];
}
NSRectFill( self.bounds );
}

The table delegate also overrides tableViewSelectionDidChange: to call setNeedsDisplay on the table. Now, if I click or use arrow keys, tableViewSelectionDidChange: does get called, but my drawBackgroundInRect: is not called.

However, if I make the window containing the table change its “main” status, then some drawBackgroundInRect: calls finally happen.

And here’s the really weird part: If I create a WindowRef for the window containing the table, like

[self.window windowRef];

then from then on I see the selection highlight changes immediately.


Alex Zavatone
 

Can you set the background to needsRefresh?

On Sep 15, 2020, at 4:54 PM, James Walker <list2@...> wrote:

I have a view-based NSTableView in a scroll view. I want to customized the way that selection highlighting is drawn. So, I set up a controller as a delegate of the table, and in the delegate method tableView:rowViewForRow: I provide an instance of a subclass of NSTableRowView, call it NameRowView. NameRowView overrides one method:

- (void) drawBackgroundInRect: (NSRect) dirtyRect
{
NSLog(@"drawBackgroundInRect %@", self);
if (self.selected)
{
[NSColor.greenColor setFill];
}
else
{
[NSColor.yellowColor setFill];
}
NSRectFill( self.bounds );
}

The table delegate also overrides tableViewSelectionDidChange: to call setNeedsDisplay on the table. Now, if I click or use arrow keys, tableViewSelectionDidChange: does get called, but my drawBackgroundInRect: is not called.

However, if I make the window containing the table change its “main” status, then some drawBackgroundInRect: calls finally happen.

And here’s the really weird part: If I create a WindowRef for the window containing the table, like

[self.window windowRef];

then from then on I see the selection highlight changes immediately.


James Walker
 

On Sep 15, 2020, at 3:05 PM, Alex Zavatone via groups.io <zav@...> wrote:

Can you set the background to needsRefresh?
I assume you mean needsDisplay. In my tableViewSelectionDidChange: delegate method, if instead of setting needsDisplay on the table, I say

[self.table enumerateAvailableRowViewsUsingBlock:
^(__kindof NSTableRowView * _Nonnull rowView, NSInteger row)
{
rowView.needsDisplay = YES;
}];

then it does show my highlights. Seems a little baroque, but it works, so thanks!



On Sep 15, 2020, at 4:54 PM, James Walker <list2@...> wrote:

I have a view-based NSTableView in a scroll view. I want to customized the way that selection highlighting is drawn. So, I set up a controller as a delegate of the table, and in the delegate method tableView:rowViewForRow: I provide an instance of a subclass of NSTableRowView, call it NameRowView. NameRowView overrides one method:

- (void) drawBackgroundInRect: (NSRect) dirtyRect
{
NSLog(@"drawBackgroundInRect %@", self);
if (self.selected)
{
[NSColor.greenColor setFill];
}
else
{
[NSColor.yellowColor setFill];
}
NSRectFill( self.bounds );
}

The table delegate also overrides tableViewSelectionDidChange: to call setNeedsDisplay on the table. Now, if I click or use arrow keys, tableViewSelectionDidChange: does get called, but my drawBackgroundInRect: is not called.

However, if I make the window containing the table change its “main” status, then some drawBackgroundInRect: calls finally happen.

And here’s the really weird part: If I create a WindowRef for the window containing the table, like

[self.window windowRef];

then from then on I see the selection highlight changes immediately.