Показывать NSPopover из токена NSTokenField при нажатии

Я пытаюсь показать NSPopover из токена NSTokenField при нажатии на токен.

Эти токены имеют встроенный способ отображения меню, поэтому с точки зрения дизайна это мало чем отличается от этого действия.

Однако не существует (хорошего) способа выполнить произвольный код при нажатии на токен.

Мне удалось вставить некоторый код в - tokenField:menuForRepresentedObject:, но это далеко не элегантно.

Предполагая, что - tokenField:menuForRepresentedObject: — единственный способ выполнить код при нажатии на токен, у меня все еще есть другая проблема: получить NSRect, представляющий токен, чтобы NSPopover мог поддерживать визуальную связь с указанным токеном. Я пытался жонглировать строками, выяснять, как появляются токены и т. д., но это далеко не надежно и даже требует недокументированного метода.

Итог: как отобразить NSPopover из выбранного токена в NSTokenField?


person Patrick Perini    schedule 23.04.2012    source источник


Ответы (3)


Я думаю, что это невозможно (см. мои усилия здесь). Проблема в том, что отдельный токен не отображается таким образом, чтобы вы могли ссылаться на его границы, чтобы подключить его с помощью всплывающего окна.

person Roger    schedule 24.04.2012

Это то, что я в итоге сделал. Я работаю над альтернативой NSTokenField с открытым исходным кодом, в которую встроена эта возможность.

// in an NSWindowController
- (NSMenu *)tokenField:(NSTokenField *)tokenField menuForRepresentedObject:(id)representedObject
{
    NSRect displayRect = NSMakeRect(([NSEvent mouseLocation].x - 2.5),
                                    ([NSEvent mouseLocation].y - 2.5),
                                    5, 5);
    displayRect = [self.window convertRectFromScreen: displayRect];


    // establish popover from displayRect ...
}

Он выглядит довольно здорово, несмотря на то, что кажется сильно взломанным (и иногда отклоняется на 1 пиксель).

person Patrick Perini    schedule 24.04.2012

Другой вариант — использовать способность NSMenuItem поддерживать произвольное представление:

- (NSMenu *)tokenField:(NSTokenField *)tokenField menuForRepresentedObject:(id)representedObject {
    NSMenu *menu = [[NSMenu alloc] init];
    NSMenuItem *item = [NSMenuItem alloc] init];
    [item setRepresentedObject: representedObject];

    NSNib *nib = [[NSNib alloc] initWithNibNamed: @"token" bundle: nil];
    [nib instantiateWithOwner: item topLevelObjects: nil];

    [menu addItem: item];
    return menu;
}

Затем вы можете создать пользовательский интерфейс, в котором владельцем файла является NSMenuItem, и он подключен к пользовательскому представлению со всем, что вы хотели во всплывающем окне. Вы можете использовать представленный объект для привязки к значениям в наконечнике.

Я на очень ранней стадии этого. Я еще не подключил свои NSManagedObjects к полю Token, и я просто использую массив строк для тестирования, но делая это таким образом, я получаю эффект, подобный Popover, за исключением маленького углового указателя. Кажется, намного лучше и проще, чем многие другие хаки, которые я видел, чтобы сделать это, исследуя это.

person Silver    schedule 06.01.2014
comment
Это хорошо, если вы не планируете использовать NSPopupButton, так как это не сработает. - person Chris; 26.02.2016