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

时间:2018-11-18 10:11:05

标签: swift xcode macos interface-builder

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

这是html中select的示例。

Drop down menu with grouped items

理想情况下,我想创建一个类似于辅助功能语言选择的下拉列表。

enter image description here

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

更新:

之所以这样做,是因为我正在向用户显示语音列表。目前,它将所有区域混合在一起,这非常令人困惑。

voice drop down

我正在处理一个更新,可以在其中显示“英语(英国)”,但在发布之前,我希望将它们分组。

3 个答案:

答案 0 :(得分:1)

以下代码组菜单,但与您提到的方式不同。

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
}()

在代码中添加popupbutton,您将获得如下结果

enter image description here

每个人都将拥有自己的物品。

答案 1 :(得分:1)

如果没有组标题,则可以使用以下代码

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
}()

结果:

enter image description here

答案 2 :(得分:1)

由于我不熟悉Swift,因此我将在Objective-C中提供答案。抱歉...不过,您应该能够轻松地翻译它,否则我相信这里有人可以做到。

因此,我通过使用以下方法制作NSMenu的子类来进行管理:

@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中,向下钻取弹出按钮,直到看到其菜单,然后将菜单的类别设置为“ MenuWithSections”。 popup button drill-down

  2. 关闭弹出按钮的“自动启用”功能(在IB的“属性”选项卡中将其关闭,或通过编程将其设置为“否”)

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

换句话说,要获得所需的外观,请像这样传递弹出按钮标题:

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

sectioned popup

或者如果您想在两组之间使用分隔线,请使用:

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

sectioned popup with divider