5

我正在使用具有源列表样式的 NSOutlineView,并使用基于视图(而不是基于单元格)的大纲视图。

我希望能够使一些行加粗。但是,我尝试更改字体(在 IB 中手动,通过 viewForTableColumn:... 中的代码,或通过 Font Bold 绑定)到目前为止都被忽略了。

从这条消息看来,这是因为 NSOutlineView 的源列表样式接管了管理文本字段的外观:

我猜您已经将文本字段连接到 NSTableCellView 的 textField 插座?如果是这样,我认为您可能会遇到 NSTableView 对源列表外观的自动管理。

尝试从 textField 插座断开文本字段,看看您的自定义字体是否粘住。

如果我断开 textField 插座,外观确实在我的控制之下,并且我的胆量起作用了。

但是,现在我无法让它看起来像自动的。我的意思是,当 NSOutlineView 管理文本字段的外观时,字体是粗体并在选择任何项目时获得阴影,但是当我手动管理它时,情况并非如此。

任何人都可以回答以下任何一个问题:

  1. 当 NSOutlineView 管理我的文本字段的外观时,如何使字体粗体绑定工作
  2. 如果我没有 NSOutlineView 管理我的文本字段的外观,我怎样才能让它看起来和表现得像我管理它时那样?
4

2 回答 2

7

我想我找到了解决方案:

NSTableCellView通过在包含控件的单元格上设置属性来管理其textField插座的外观。backgroundStyle将此设置为NSBackgroundStyleDark触发一个特殊的路径,NSTextFieldCell其中基本上设置一个attributedStringValue,更改文本颜色并通过添加阴影NSShadowAttributeName

你能做的有两件事:

  • 在自定义行或单元格视图子类中自行设置backgroundStyle
  • 在单元格的文本字段中使用自定义NSTextFieldCell并更改行为/绘图。

我们做了后者,因为我们需要一个不同的外观主题(不同颜色)的表格视图。我们为此找到的最方便(尽管肯定不是最有效)的位置是- drawInteriorWithFrame:inView:在调用 super 之前覆盖和修改单元格的属性字符串,然后恢复原始字符串:

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    NSAttributedString *originalString = self.attributedStringValue;

    // Customize string as you like
    if (/* whatever */)
        [self setAttributedStringValue: /* some string */];

    // Regular drawing
    [super drawInteriorWithFrame:cellFrame inView:controlView];

    // Reset string
    if (self.attributedStringValue != originalString)
        self.attributedStringValue = originalString;
}

希望这可以帮助其他处于类似情况的人。

于 2013-03-12T22:05:39.287 回答
0

不确定我是否遗漏了您的问题中的任何内容,但使用以下方法更改字体对我有用。ReminderTableCellView只是 NSTableCellView 的一个子类,添加了一个额外的 dateField。

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    //LOG(@"viewForTableColumn called");
    // For the groups, we just return a regular text view.
    if ([_topLevelItems containsObject:item]) {
        //LOG(@" top level");
        NSTableCellView *result = [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self];
        // Uppercase the string value, but don't set anything else. NSOutlineView automatically applies attributes as necessary
        NSString *value = [item uppercaseString];
        [result.textField setStringValue:value];
        //[result.textField setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
        return result;
    } else  {
        //LOG(@" menu item");
        // The cell is setup in IB. The textField and imageView outlets are properly setup.
        // Special attributes are automatically applied by NSTableView/NSOutlineView for the source list
        ReminderTableCellView *result = [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
        if ([item isKindOfClass:[OSTreeNode class]]) {
            [result.textField setFont:[NSFont boldSystemFontOfSize:13]];
            result.textField.stringValue = [item displayName];
            result.dateField.stringValue = [item nextReminderDateAsString];
        }
        else
            result.textField.stringValue = [item description];
        if (_loading)
            result.textField.textColor = [NSColor grayColor];
        else
            result.textField.textColor = [NSColor textColor];
        NSImage *image = [NSImage imageNamed:@"ReminderMenuIcon.png"];
        [image setSize:NSMakeSize(16,16)];
        [result.imageView setImage:image];
        //[result.imageView setImage:nil];
        return result;
    }
}

生成的视图如下所示。请注意,这是一个选择了源列表选项的 NSOutlineView,但我不明白为什么这对普通的 outlineView 不起作用。

在此处输入图像描述

于 2013-09-14T00:08:20.743 回答