NSTableRowView / NSTableCellView how to set own color in the selected line?

I am trying to implement a custom row color when selecting a table row.

-(void)tableViewSelectionDidChange:(NSNotification *)notification{ NSInteger selectedRow = [_mainTable selectedRow]; NSTableCellView *cell = [_mainTable rowViewAtRow:selectedRow makeIfNecessary:NO]; cell.layer.backgroundColor = [NSColor redColor].CGColor; NSLog(@"selected"); } 

But that does not work. I find that Apple's documentation is very confusing (maybe I'm wrong). I have no Mac programming experience.

Can anyone suggest any solution? Basically, I need this color to be transparent.

+6
source share
3 answers

The first selection highlighting style for selecting a table is

  NSTableViewSelectionHighlightStyleNone 

then in your tablView delegate implement

 tableView:shouldSelectRow: 

and write this code in it:

 NSTableViewRow *row= [_mainTable rowViewAtRow:selectedRow makeIfNecessary:NO]; row.backgroundColor = [your color]; return YES; 

read this also https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSTableViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/NSTableViewDelegate/tableView:rowViewForRow :

for style selection https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTableView_Class/index.html#//apple_ref/occ/instp/NSTableView/selectionHighlightStyle

+6
source

Decision

This should be done by subclassing NSTableRowView , and then returning your subclass using the NSTableView delegate NSTableView
-(NSTableRowView*)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row

The NSTableRowView subclass provides much greater flexibility when changing the appearance of a row. Returning your subclass in the NSTableView delegate NSTableView above will also automatically remove the background highlight color when clicking one row on another (which is an open problem in the other answer).


Steps

First subclass NSTableRowView and override drawSelectionInRect to change its background color when selected:

 @implementation MyTableRowView - (void)drawSelectionInRect:(NSRect)dirtyRect { [super drawSelectionInRect:dirtyRect]; [[NSColor yellowColor] setFill]; NSRectFill(dirtyRect); } 

Then return the subclass of the row using the delegation method rowViewForRow NSTableView :

 - (NSTableRowView*)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row { static NSString* const kRowIdentifier = @"MyTableRow"; MyTableRowView* myRowView = [tableView makeViewWithIdentifier:kRowIdentifier owner:self]; if (!myRowView) { myRowView = [[MyTableRowView alloc] initWithFrame:NSZeroRect]; myRowView.identifier = kRowIdentifier; } return rowView; } 

Using this approach, you can also easily override other elements, such as the color of the separator. To do this, override the drawSeparatorInRect method in the drawSeparatorInRect subclass as follows:

 - (void)drawSeparatorInRect:(NSRect)dirtyRect { // Change the separator color if the row is selected if (self.isSelected) [[NSColor orangeColor] setFill]; else [[NSColor grayColor] setFill]; // Fill the seperator dirtyRect.origin.y = dirtyRect.size.height - 1.0; dirtyRect.size.height = 1.0; NSRectFill(dirtyRect); } 

Resources

Overriding NSTableRowView Display NSTableRowView https://developer.apple.com/reference/appkit/nstablerowview

NSTableview rowViewForRow delegate method https://developer.apple.com/reference/appkit/nstableviewdelegate/1532417-tableview

+12
source

This is necessary to set a custom color for the selected line, as well as for the selected text color. The output should look something like this

enter image description here

In the above screenshot we do

  • Setting the selected background to white

  • Adding a corner radius

  • Change text color to blue

  • Adding a Blue Stroke

You can do a lot more customization, but this answer covers the above questions.

1. Start by subclassing NSTableRowView

 class CategoryTableRowView: NSTableRowView { override func drawSelection(in dirtyRect: NSRect) { if selectionHighlightStyle != .none { let selectionRect = bounds.insetBy(dx: 2.5, dy: 2.5) NSColor(calibratedRed: 61.0/255.0, green: 159.0/255.0, blue: 219.0/255.0, alpha: 1.0).setStroke() NSColor(calibratedWhite: 1.0, alpha: 1.0).setFill() let selectionPath = NSBezierPath(roundedRect: selectionRect, xRadius: 25, yRadius: 25) selectionPath.fill() selectionPath.stroke() } } } 

2. Return the custom CategoryTableRowView () in the NSTableViewDelegate method

 func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? { return CategoryTableRowView() } 

3. Make sure you have a selectionHighlightStyle for the normal ViewController in your class

 override func viewDidLoad() { super.viewDidLoad() self.tableView.selectionHighlightStyle = .regular } 

4. To set textColor, subclass NSTableCellView

 class CategoryCellView: NSTableCellView { @IBOutlet weak var categoryTextField: NSTextField! override var backgroundStyle: NSView.BackgroundStyle { willSet{ if newValue == .dark { categoryTextField.textColor = NSColor(calibratedRed: 61.0/255.0, green: 159.0/255.0, blue: 219.0/255.0, alpha: 1.0) } else { categoryTextField.textColor = NSColor.black } } } } 

override the backgroundStyle property and set the desired color for the text.

Note. In my case, I have a custom cell with categoryTextField output. To set the text color I use: categoryTextField.textColor = NSColor.black

5. Set a custom class inside the storyboard enter image description here

Hope this helps. Thank you

0
source

Source: https://habr.com/ru/post/1205620/


All Articles