是否可以在 NSPopupButton 中对项目进行分组?

Is it possible to group items in a NSPopupButton?

我正在尝试显示系统语音列表,但我想按地区对它们进行分组。

这是 html 中 select 的示例。

理想情况下,我想创建一个类似于辅助功能语言的下拉菜单 selection。

有什么方法可以在 Interface Builder 中复制它/swift? 任何指针将不胜感激。

更新:

这是因为我正在向用户显示语音列表。目前,它把所有的区域都混在一起了,这很混乱。

我正在做一个更新,我可以在其中显示 "English (United Kingdom)",但我想在发布之前将它们分组。

下面的代码组菜单,但不像你说的那样。

let items = [["First","Second"],["First","Second"],["First","Second"]]

lazy var addNewViewButton : NSPopUpButton = {
    let popupButton = NSPopUpButton()

    let firstMenuItem = NSMenuItem(title: "First Group", action: nil, keyEquivalent: "")
    let secondMenuItem = NSMenuItem(title: "Second Group", action: nil, keyEquivalent: "")
    let thirdMenuItem = NSMenuItem(title: "Third Group", action: nil, keyEquivalent: "")

    let superMenu = NSMenu()
    superMenu.addItem(firstMenuItem)
    superMenu.addItem(secondMenuItem)
    superMenu.addItem(thirdMenuItem)

    for (index,item) in items.enumerated()
    {
        let menu = NSMenu()
        for title in item
        {
            let menuItem = NSMenuItem(title: title, action: nil, keyEquivalent: "")
            menuItem.target = self
            menu.addItem(menuItem)
        }
        menu.addItem(NSMenuItem.separator())
        superMenu.setSubmenu(menu, for: superMenu.items[index])
    }
    popupButton.menu = superMenu

    popupButton.translatesAutoresizingMaskIntoConstraints = false

    return popupButton
}()

在你的代码中添加弹出按钮,你会得到这样的结果

每一个里面都会有自己的物品。

如果没有群头,可以使用下面的代码

let items = [["First","Second"],["First","Second"],["First","Second"]]

lazy var addNewViewButton : NSPopUpButton = {
    let popupButton = NSPopUpButton()

    let menu = NSMenu()
    for item in items
    {
        for title in item
        {
            let menuItem = NSMenuItem(title: title, action: nil, keyEquivalent: "")
            menuItem.target = self
            menu.addItem(menuItem)
        }
        menu.addItem(NSMenuItem.separator())
    }
    popupButton.menu = menu

    popupButton.translatesAutoresizingMaskIntoConstraints = false

    return popupButton
}()

结果:

我将在 Objective-C 中提供答案,因为我不在 Swift 中。抱歉...不过你应该能够很容易地翻译它,否则我相信这里有人可以做到。

因此,我通过使用以下方法创建 NSMenu 的子class 来管理它:

@implementation MenuWithSections

- (NSMenuItem*)insertItemWithTitle:(NSString*)aString action:(SEL)aSelector keyEquivalent:(NSString*)keyEquiv atIndex:(NSInteger)index
{
    NSMenuItem * item;
    NSString * adjustedString;

    if ([aString isEqualToString:menuDividerString]) {
        NSMenuItem *separator = [NSMenuItem separatorItem];
        [self insertItem:separator atIndex:index];
        return separator;
    } else if ([aString hasPrefix:menuSectionHeaderPrefix]) {
        adjustedString = [[aString substringFromIndex:menuSectionHeaderPrefix.length] capitalizedString];
        NSMenuItem * sectionHead =  [[NSMenuItem alloc] initWithTitle:adjustedString
                                                           action:nil
                                                    keyEquivalent:@""];
        sectionHead.enabled = NO;
        sectionHead.indentationLevel = 0;
        [self insertItem:sectionHead atIndex:index];
        return sectionHead;
    } 

    item = [super insertItemWithTitle:aString action:aSelector keyEquivalent:keyEquiv atIndex:index];
    item.indentationLevel = 1;
    return item;
}

@end

menuDividerString 在我的例子中是@"----",而 menuSectionHeaderPrefix 是@"..";请参阅下面的示例。

要让它发挥作用,请做三件事:

  1. 在IB中,向下钻取弹出按钮直到看到它的菜单,然后将菜单的class设置为'MenuWithSections'。 popup button drill-down

  2. 关闭弹出按钮的'autoenable'功能(在IB的'Attributes'选项卡中点击关闭,或者编程设置为NO)

  3. 使用上述常量传入修改后的字符串以获得所需的效果。

换句话说,要在您的问题中获得您想要的外观,请像这样传递弹出按钮标题:

[self.popbutton addItemsWithTitles:@[ @"..swedish cars", @"Volvo", @"Saab", @"..German cars", @"Mercedes", @"Audi"]];

sectioned popup

或者如果你想在两组之间有一个 divider-line,使用:

[self.popbutton addItemsWithTitles:@[ @"..swedish cars", @"Volvo", @"Saab", @"----", @"..German cars", @"Mercedes", @"Audi"]];

sectioned popup with divider