2012-01-03 39 views
1

我正在使用基于视图的NSTableView,并且遇到了一个小问题。NSTableView单元显示问题

我试图在突出显示时将我的两个标签的文本颜色从黑色切换到白色。

要做到这一点,我已经写了下面的代码,

- (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(或任何它被称为)。

当textField不可见时(滚动离开它然后返回),颜色也会切换回黑色。再一次,即使这样做,NSTextField的颜色仍然记录为白色。

回答

1

在NSTableViewCell上重写setBackgroundStyle对我来说是完美的,至少在OS X 10.8上是完美的。 (考虑到SO中的相关问题的数量,人们可以猜到以前曾经有过一些问题。)

背景风格在选择事件和窗口激活/停用方面更新,就像人们所期望的那样。

这里是我的自定义单元格IMPL - 微不足道,因为它可以得到:

@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 2016-11-24 03:38:38

0

我的方法是非常哈克,而且可能不是最佳的解决方案;但它解决了它,所以这很好。

假设你按照我的方式实现了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; 
    } 
} 

事情应该正确显示。