NSOutlineView源列表样式,基于视图,更改字体。

5
我正在使用源列表样式的NSOutlineView,并使用基于视图而非单元格的大纲视图。我想使一些行变为粗体。但是,我尝试改变字体(在IB中手动更改,在viewForTableColumn:…中通过代码或通过Font Bold绑定),但迄今为止都被忽略了。从这条消息this message中可以看出,这是因为NSOutlineView的源列表样式接管了文本字段的外观管理:
我猜你已经将文本字段连接到了NSTableCellView的textField输出?如果是这样,我认为你可能会遇到NSTableView自动管理源列表外观的问题。尝试断开textField输出并查看自定义字体是否生效。如果我断开textField输出,外观就会受到我的控制,我的加粗也会生效。
然而,现在我无法使它看起来像自动的那个。我的意思是,当NSOutlineView管理文本字段的外观时,字体会加粗并在选择任何项目时获得投影效果,但是当我手动管理它时,情况并非如此。
有人能回答以下问题吗:
1. 当NSOutlineView管理文本字段的外观时,我该如何使字体加粗绑定生效? 2. 如果我不让NSOutlineView管理文本字段的外观,我该如何使其看起来和行为像我让它管理时一样?

自从问题被提出以来,有任何收获吗?我也遇到了类似的问题 :( - Max Seelemann
我想我放弃了,使用了一个图标而不是更改字体。这可能是可行的,但我从未找到如何实现。 - Amy Worrall
2个回答

7
我认为我找到了解决方案: NSTableCellView 通过在包含的控件中设置 backgroundStyle 属性来管理其 textField 出口的外观。将此设置为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;
}

希望这能帮助到其他遇到类似问题的人。

谢谢你。这很有帮助。 - Tommy

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不起作用。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接