2012-01-03 5 views
1

Я использую NSTableView на основе представления, и я столкнулся с небольшой проблемой.NSTableView Cell Display Issue

Я пытаюсь переключить цвет текста моих двух меток от черного до белого, когда выделено.

Чтобы сделать это, я написал следующий код,

- (void)tableViewSelectionDidChange:(NSNotification *)notification 
{ 
    NSView * viewInQuestion = [table viewAtColumn:0 row:[table selectedRow] makeIfNecessary:YES]; 

    if ([viewInQuestion isNotEqualTo:lastViewSelected]) 
    { 
     [(NSTextField*)lastViewSelected.subviews.lastObject setTextColor:NSColor.blackColor]; 
     [(NSTextField*)[lastViewSelected.subviews objectAtIndex:1] setTextColor:NSColor.grayColor]; 
    } 

    [(NSTextField*)viewInQuestion.subviews.lastObject setTextColor:NSColor.whiteColor]; 
    [(NSTextField*)[viewInQuestion.subviews objectAtIndex:1] setTextColor:NSColor.whiteColor]; 

    lastViewSelected = viewInQuestion; 
} 

Это прекрасно работает; Я получаю этот результат:

Вопрос заключается в том, что иногда текст не появляется белым, даже при том, что NSLog сказала мне, что цвет NSTextField был NSCalibratedWhite (или как там это называется).

Цвет также переключается обратно на черный, когда текстовый экран не виден (прокрутка от него, а затем назад). Опять же, даже когда он делает это, цвет NSTextField по-прежнему записывается как белый.

ответ

1

Переопределение setBackgroundStyle на NSTableViewCell отлично работает для меня, по крайней мере, на OS X 10.8. (Учитывая количество соответствующих вопросов здесь, на SO, можно догадаться, что раньше были какие-то проблемы).

Фоновый стиль обновляется в событиях выбора и активации/деактивации окна, как и следовало ожидать.

Вот мои пользовательские ячейки осущий - так тривиален, как он может получить:

@implementation RuntimeInstanceCellView 

- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle { 
    [super setBackgroundStyle:backgroundStyle]; 
    self.detailTextField.textColor = (backgroundStyle == NSBackgroundStyleLight ? [NSColor darkGrayColor] : [NSColor colorWithCalibratedWhite:0.85 alpha:1.0]); 
// self.detailTextField.textColor = (backgroundStyle == NSBackgroundStyleLight ? [NSColor blackColor] : [NSColor whiteColor]); 
} 

@end 
+0

Изменения ответа на решение, это не совсем оптимальное для обработки стилей фона, как я сделал. – evdude100

0

Мой метод очень Hacky, и, вероятно, не является оптимальным решением; Но он решает это, так что это хорошо.

Предполагая, что вы внедрили tableSelectionDidChange, как у меня есть, все, что вам нужно сделать, это зарегистрировать NSNotification и реализовать собственный метод, который должен быть более явным.

В INIT, проснись, или didFinishLaunching часть вашего приложения ...

NSView * contentView = table.enclosingScrollView.contentView; 
[contentView setPostsFrameChangedNotifications:YES]; 
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(boundsDidChange:) name:NSViewBoundsDidChangeNotification object:contentView]; 

Где-то в программе ...

(при условии, hasUpdatedCell булева свойство)

- (void)boundsDidChange:(NSNotification *)notification 
{ 
    /* Bounds can change while nothing is selected--> but we only want to execute the method if a cell is selected. */ 

    if ([table selectedRow] == -1) {return;} 

    NSRect visibleRect = table.enclosingScrollView.visibleRect; 
    NSView * viewInQuestion = [table viewAtColumn:0 row:[table selectedRow] makeIfNecessary:YES]; 
    NSPoint selectedViewOrigin = [viewInQuestion convertPoint:viewInQuestion.frame.origin toView:table.enclosingScrollView]; 

    /* If the selected cell is visible, then we can go ahead and redraw the white text as a part of the workaround. 
     This is because scrolling away from the selected cell and back will make the cell revert back to black. */ 

    BOOL cellVisible = NSPointInRect(selectedViewOrigin, visibleRect); 

    /* We already know we need to update it, and we will so we don't need to evaluate the next step in the program */ 

    if (!cellVisible && !hasUpdatedCell) {return;} 


    if (cellVisible && !hasUpdatedCell) 
    { 
     /* The cell is visible but we haven't updated. Let's do it then. */ 

     [self tableViewSelectionDidChange:nil]; 
     hasUpdatedCell = YES; 
    } 
    else if (!cellVisible) 
    { 
     /* The cell is not visible and we need to update next time. */ 

     hasUpdatedCell = NO; 
    } 
} 

Вещи должны отображаться должным образом.