带有attributesTitle的NSMenuItem在macOS 10.12.2 Sierra中不起作用

时间:2016-12-19 21:47:14

标签: objective-c cocoa nsattributedstring macos-sierra nsmenuitem

我创建了一个文件名和修改日期菜单。我使用属性字符串对齐这些字符串,并设置制表位以适合最长的文件名。这适用于macOS 10.8-10.11。

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

macOS10.11 menu

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

macOS10.12 menu

所有平台上的代码都是相同的:

#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];
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

我发现将NSParagraphStyle's firstLineHeadIndentheadIndent属性设置为大于0的数字会让它重新开始工作。

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