Раскраски строк в режиме просмотра на основе NSTableview
У меня есть nStableview, основанный на представлении. Я хочу покрасить всю строку на основе некоторого условия, для которого я использовал код ниже
- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row
{
NSTableRowView *view = [[NSTableRowView alloc] initWithFrame:NSMakeRect(1, 1, 100, 50)];
[view setBackgroundColor:[NSColor redColor]];
return view;;
}
Вызывается метод delegate, но таблица, похоже, не использует NSTableRowView
, возвращенный методом делегирования.
Основная цель - раскрасить целую строку на основе некоторого состояния. Что неправильно в реализации выше?
Ответы
Ответ 1
Для всех, кто это делает и хочет создать настраиваемый NSTableRowView backgroundColor, существует два подхода.
-
Если вам не нужен пользовательский чертеж, просто установите rowView.backgroundColor
в - (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row
в NSTableViewDelegate
.
Пример:
- (void)tableView:(NSTableView *)tableView
didAddRowView:(NSTableRowView *)rowView
forRow:(NSInteger)row {
rowView.backgroundColor = [NSColor redColor];
}
-
Если вам нужен пользовательский чертеж, создайте свой собственный подкласс NSTableRowView
с нужным drawRect
. Затем выполните следующее в NSTableViewDelegate
:
Пример:
- (NSTableRowView *)tableView:(NSTableView *)tableView
rowViewForRow:(NSInteger)row {
static NSString* const kRowIdentifier = @"RowView";
MyRowViewSubclass* rowView = [tableView makeViewWithIdentifier:kRowIdentifier owner:self];
if (!rowView) {
// Size doesn't matter, the table will set it
rowView = [[[MyRowViewSubclass alloc] initWithFrame:NSZeroRect] autorelease];
// This seemingly magical line enables your view to be found
// next time "makeViewWithIdentifier" is called.
rowView.identifier = kRowIdentifier;
}
// Can customize properties here. Note that customizing
// 'backgroundColor' isn't going to work at this point since the table
// will reset it later. Use 'didAddRow' to customize if desired.
return rowView;
}
Ответ 2
Наконец, он работал как ниже
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSView *cellView = (NSView*) [tableView makeViewWithIdentifier:[tableColumn identifier] owner:[tableView delegate]];
CALayer *viewLayer = [CALayer layer];
[viewLayer setBackgroundColor:[[NSColor redcolor] CGColor]];
[cellView setWantsLayer:YES];
[cellView setLayer:viewLayer];
return cellView;
}
Обратите внимание, что вам нужно преобразовать nscolor в cgcolor, который вы можете найти в https://gist.github.com/707921 или http://forrst.com/posts/CGColor_Additions_for_NSColor-1eW
Ответ 3
Если вы просматриваете презентацию на основе таблиц на основе WWDC 2011, вы увидите, что основная идея - создать представления в Interface Builder, а затем получить их оттуда. Что-то вроде:
[tableView makeViewWithIdentifier:@"GroupRow" owner:self];
Как только вы получили представление, просто установите его свойства и верните его.
Обратите внимание, что в этом примере у него есть свой собственный идентификатор, поэтому не забудьте установить его, но вы также можете использовать автоматические идентификаторы.
Я не знаю, будет ли прямая ссылка на WWDC работать, но главная страница здесь: https://developer.apple.com/videos/wwdc/2011/, и если вы найдите "Просмотр на основе NSTableView Basic to Advanced", вы найдете его. Это стоит посмотреть.
Ответ 4
Я повторно написал слойный подход.
В Swift 3.2
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let greenCell = self.tableview.make(withIdentifier: "green", owner: self)
let layer:CALayer = CALayer()
layer.backgroundColor = NSColor.green.cgColor
greenCell?.wantsLayer = true
greenCell?.layer = layer
return greenCell
}
Не забудьте изменить идентификатор ячейки в соответствии с раскадрой, а в идентификаторе кода - "зеленый". И, конечно, цвет фона, если вы хотите.