我正在使用基于视图的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的颜色仍然记录为白色。
答案 0 :(得分: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
答案 1 :(得分:0)
我的方法非常hacky,可能不是最佳解决方案;但它解决了它,所以这很好。
假设你按照我的方式实现了tableSelectionDidChange,你需要做的就是注册一个NSNotification并实现一个更明确的自定义方法。
在init,awake或didFinishLaunching应用程序的一部分......
NSView * contentView = table.enclosingScrollView.contentView;
[contentView setPostsFrameChangedNotifications:YES];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(boundsDidChange:) name:NSViewBoundsDidChangeNotification object:contentView];
该计划的其他地方......
(假设hasUpdatedCell是BOOLEAN属性)
- (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;
}
}
然后事情应该正确显示。