Показывать меню NSSegmentedControl при щелчке по сегменту, несмотря на установленное действие - PullRequest
7 голосов
/ 30 июля 2009

У меня есть NSSegmentedControl на моем интерфейсе с 4 кнопками.Элемент управления связан с методом, который будет вызывать различные методы в зависимости от того, какой сегмент нажат:

- (IBAction)performActionFromClick:(id)sender {
    NSInteger selectedSegment = [sender selectedSegment];
    NSInteger clickedSegmentTag = [[sender cell] tagForSegment:selectedSegment];

    switch (clickedSegmentTag) {
            case 0: [self showNewEventWindow:nil]; break;
            case 1: [self showNewTaskWindow:nil]; break;
            case 2: [self toggleTaskSplitView:nil]; break;
            case 3: [self showGearMenu]; break;
    }
}

Сегмент 4 имеет привязанное к нему меню в методе awakeFromNib.Я бы хотел, чтобы это меню выпадало, когда пользователь щелкает сегмент.На данный момент, он будет только выпадать, если пользователь нажимает и удерживает в меню.Из моих онлайн-исследований это связано с действием.

В настоящее время я работаю над этим, используя некоторый код для получения исходной точки элемента управления сегментом и вызывая контекстное меню, используя NSMenu popUpContextMenu:withEvent:forView, но это довольно хактично и выглядит плохо по сравнению со стандартным поведениемиметь выпадающее меню под сегментированной управляющей ячейкой.

Есть ли способ, которым я могу сделать выпадающее меню, как это должно быть после одного щелчка мышью, вместо того, чтобы делать хакерские вещи контекстного меню?

Ответы [ 4 ]

17 голосов
/ 27 июля 2010

Подкласс NSSegmentedCell, переопределите метод ниже и замените класс ячейки в IB. (Не требует никаких частных API).

- (SEL)action
{
    //this allows connected menu to popup instantly (because no action is returned for menu button)
    if ([self tagForSegment:[self selectedSegment]]==0) {
        return nil;
    } else {
        return [super action];
    }
}
4 голосов
/ 27 апреля 2015

Это версия Swift от J Hoover и мод от Adam Treble. Переопределение не было настолько интуитивно понятным, как я думал, так что, надеюсь, это поможет кому-то еще.

override var action : Selector {
        get {
            if self.menuForSegment(self.selectedSegment) != nil {
                return nil
            }
            return super.action
        }
        set {
            super.action = newValue
        }
    }
3 голосов
/ 30 июля 2009

Я не уверен, что есть какой-либо встроенный способ сделать это (хотя это действительно явная дыра в API NSSegmentedControl).

Моя рекомендация - продолжать делать то, что вы делаете, открывая контекстное меню. Однако вместо того, чтобы просто использовать происхождение сегментированного элемента управления, вы можете расположить его непосредственно под сегментом (как вы хотите), выполнив следующее:

NSPoint menuOrigin = [segmentedControl frame].origin;
menuOrigin.x = NSMaxX([segmentedControl frame]) - [segmentedControl widthForSegment:4];
// Use menuOrigin where you _were_ just using [segmentedControl frame].origin

Она не идеальна и не идеальна, но должна выполнять свою работу и давать вид / поведение, которого ожидают пользователи.

(кроме этого, NSSegmentedControl действительно нуждается в методе -rectForSegment:)

2 голосов
/ 06 мая 2010

widthForSegment: возвращает ноль, если размер сегмента авторазмерен. Если вы не обеспокоены недокументированными API, существует rectForSegment:

  • rectForSegment (NSRect): (NSInteger) сегмент в рамке считывания: (NSRect) кадр; * +1004 *

Но чтобы ответить на первоначальный вопрос, более простой способ заставить меню всплыть немедленно - это создать подкласс NSSegmentedCell и вернуть 0 для (опять же, недокументированного)

  • (двойной) _menuDelayTimeForSegment: (NSInteger) сегмент;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...