具有 attributedTitle 的 NSMenuItem 在 macOS 10.12.2 Sierra 中不起作用

NSMenuItem with attributedTitle not working in macOS 10.12.2 Sierra

我创建了一个文件名和修改日期的菜单。我使用带有制表位设置的属性字符串对齐它们以适应最长的文件名。这在 macOS 10.8-10.11 上运行良好。

菜单应该是这样的 - 在 macOS 10.11 和 10.12.1 上:

在 Sierra 10.12.2 上它现在看起来像这样:

各平台代码相同:

#define FILEICONSIZE         16.0
#define FILEDATELEADINGSPACE 16.0

...

- (void)rebuildMenu:(NSMenu *)menu fromFiles:(NSMutableArray <FileRepresentation *> *)files
{
    NSMenuItem *item = [menu itemWithTitle:NSLocalizedString(@"Open iCloud", nil)];
    NSMenu *icloudFilesMenu = item.submenu;
    if (!icloudFilesMenu)
        return;

    static NSImage *icon;
    if (!icon) {
        icon = [NSImage imageNamed:@"SSDoc"];
        icon.size = NSMakeSize(FILEICONSIZE, FILEICONSIZE);
    }

    [icloudFilesMenu removeAllItems];

    NSDictionary *stdAttributes = @{ NSFontAttributeName: [NSFont menuBarFontOfSize:0] };
    NSDictionary *ttAttributes  = @{ NSFontAttributeName: [NSFont toolTipsFontOfSize:0] };

    // get max width of filename
    CGFloat maxWidth = 0;
    for (FileRepresentation *f in files) {
        NSMutableAttributedString *attribTitle;

        attribTitle = [[[NSAttributedString alloc] initWithString:f.fileName attributes:stdAttributes] mutableCopy];
        [attribTitle addAttribute:NSParagraphStyleAttributeName
                            value:[NSParagraphStyle defaultParagraphStyle]
                            range:NSMakeRange(0, f.fileName.length)];
        NSRect rect = [attribTitle boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)
                                                options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading];
        if (rect.size.width > maxWidth)
            maxWidth = rect.size.width;
    }
    maxWidth += FILEDATELEADINGSPACE;
    NSMutableParagraphStyle *tabbedStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    tabbedStyle.tabStops = @[[[NSTextTab alloc] initWithTextAlignment:NSLeftTextAlignment location:maxWidth options:@{}]];

    // build file menu
    for (FileRepresentation *f in files) {
        NSMutableAttributedString *attribTitle;
        NSString *fname;

        fname = [f.fileName stringByAppendingString:@"\t"];
        item = [[NSMenuItem alloc] initWithTitle:fname action:@selector(openFile:) keyEquivalent:@""];

        attribTitle = [[[NSAttributedString alloc] initWithString:fname attributes:stdAttributes] mutableCopy];
        [attribTitle addAttribute:NSParagraphStyleAttributeName
                            value:tabbedStyle
                            range:NSMakeRange(0, fname.length)];

        // append file date in tool tip font
        if (f.modDate) {
            NSAttributedString *attribfDate;
            NSString *fdate = [((AppController *)[(NSApplication *)NSApp delegate]).fileDateFormatter stringFromDate:f.modDate];
            attribfDate = [[NSAttributedString alloc] initWithString:fdate attributes:ttAttributes];
            [attribTitle appendAttributedString:attribfDate];
        }

        item.attributedTitle = attribTitle;
        item.target = self;
        item.enabled = YES;
        item.representedObject = f.url;
        item.image = icon;

        [icloudFilesMenu addItem:item];
    }
}

有什么想法吗?

我发现将 NSParagraphStyle's firstLineHeadIndentheadIndent 属性 设置为大于 0 的数字会使其再次工作。

tabbedStyle.tabStops   = ... 
tabbedStyle.headIndent = DBL_EPSILON; // A tiny number so the indent is not noticeable