NSMenu в Objective C — Xcode Mac OS

Как совсем отключить контекстное меню для NSTextField

Правый клик мыши запускает всплывающее контекстное меню. Чтобы его отключить насовсем, необходимо создать подкласс для NSTextField (или для NSTextView) и в методе -textView:menu:forEvent:atIndex: нужно возвращать nil.

 

//------------------------------------------------------------------------//
// Отключение контекстного меню для NSTextView.
// Правый клик мыши запускает всплывающее контекстное меню. Чтобы его
// отключить насовсем, необходимо создать подкласс для NSTextField и в
// методе -textView:menu:forEvent:atIndex: нужно возвращать nil.
//------------------------------------------------------------------------//

- (NSMenu *)textView:(NSTextView *)view menu:(NSMenu *)menu forEvent:(NSEvent *)event atIndex:(NSUInteger)charIndex {
    return nil;
}

 

Как для NSTextField заменить системное контекстное меню на свое

В основном коде необходимо создать свое NSMenu и подключить его к вашему редактору текста (NSTextField, NSTextView). После этого, необходимо создать подкласс для NSTextField (или для NSTextView). В данном подклассе в методе -textView:menu:forEvent:atIndex: создаете пустой объект меню NSMenu и верните его через return.

 

//------------------------------------------------------------------------//
// Подмена контекстного меню для NSTextField (NSTextView).
// Если нам нужно подменить системное контекстное меню на свое меню, то
// обязательно нужно здесь создать пустое NSMenu *result и его возвратить,
// а нужное меню уже подхватится из storyboard или из кода. Если нужно
// возвращать системное меню, тогда просто сделайте: return menu;
//------------------------------------------------------------------------//

- (NSMenu *)textView:(NSTextView *)view menu:(NSMenu *)menu forEvent:(NSEvent *)event atIndex:(NSUInteger)charIndex {
    NSMenu *result = [super menuForEvent: event];
    return result;
}

 

Контекстное меню при клике левой кнопкой мыши по NSView

Совет: Т.к. в данном примере мы на лету (программно) создаем меню из двух пунктов непосредственно уже при клике мышью, то горячие клавишы будут работать только при открытом меню. Поэтому, если хотите, чтобы сами горячие клавиши работали и без открытия меню, то рекомендуется создавать объект меню (с пунктами меню) заранее, вне даннного метода.

А также приведены примеры, как указывать вызов разных селекторов.

 

//  ViewController.m

//------------------------------------------------------------------------//
// Запустить контекстное меню при клике левой кнопкой мыши по
// представлению NSView.
//------------------------------------------------------------------------//
// Совет: Т.к. в данном примере мы на лету (программно) создаем меню из
// двух пунктов непосредственно уже при клике мышью, то горячие клавишы
// будут работать только при открытом меню. Поэтому, если хотите, чтобы
// сами горячие клавиши работали и без открытия меню, то рекомендуется
// создавать объект меню (с пунктами меню) заранее, вне даннного метода.
//------------------------------------------------------------------------//

- (void)mouseDown:(NSEvent *)theEvent {
    NSLog(@"mouseDown");
    
    // Создаем объект меню NSMenu.
    NSMenu *theMenu = [[NSMenu alloc] initWithTitle:@"Contextual Menu"];
    
    // Создаем пункт меню Menu 1 с горячими клавишами (Shift+Cmd+t)
    NSMenuItem *theMenuItem00 = [[NSMenuItem alloc] initWithTitle: @"Menu 1" action: @selector(clickMenu1:) keyEquivalent: @""];
    [theMenuItem00 setKeyEquivalentModifierMask: NSShiftKeyMask | NSCommandKeyMask];
    [theMenuItem00 setKeyEquivalent:@"t"];
    [theMenu addItem: theMenuItem00];
    
    // Создаем пункт меню Menu 1 с горячими клавишами (Shift+Cmd+r)
    NSMenuItem *theMenuItem01 = [[NSMenuItem alloc] initWithTitle: @"Menu 2" action: @selector(clickMenu2) keyEquivalent: @""];
    [theMenuItem01 setKeyEquivalentModifierMask: NSShiftKeyMask | NSCommandKeyMask];
    [theMenuItem01 setKeyEquivalent:@"r"];
    [theMenu addItem: theMenuItem01];
    
    // Или такой вариант двух пунктов меню (горячие клавиши не указаны).
    //[theMenu insertItemWithTitle:@"Beep" action:@selector(clickMenu1:) keyEquivalent:@"" atIndex:0];
    //[theMenu insertItemWithTitle:@"Honk" action:@selector(clickMenu2) keyEquivalent:@"" atIndex:1];
    
    // Запускаем меню.
    [NSMenu popUpContextMenu:theMenu withEvent:theEvent forView:self.view];
}

// Метод для первого пункта меню.
- (IBAction)clickMenu1:(id)sender {
    NSLog(@"clickMenu1");
}

// Метод для второго пункта меню.
- (void)clickMenu2 {
    NSLog(@"clickMenu2");
}

 

Как отключить назойливый пункт контекстного меню - Services (Службы)

В нашем контекстном меню мы периодически видим, как туда самопроизвольно добавляется пункт типа Services (Службы). И обычно этот пункт появляется только тогда, когда какой-то текст или объект у вас выделен мышью или иным способом и вы кликаете правой кнопкой, вызывая контекстное меню. На самом деле данный пункт меню предназначен для плагинов, внешних программ. Они в него добавляют нам всякие возможности, абсолютно нас не спрашивая об этом. Чтобы отключить такое поведение и сделать наше меню чистым и приятным, без лишнего мусора, нужно в объекте меню установить переменную allowsContextMenuPlugIns в значение NO. Тем самым мы запретим нам гадить. Данная переменная определяет, могут ли быть добавлены плагины контекстного меню в наше меню, если они используются в качестве контекстного меню. По умолчанию используется значение YES.

 

// Отключаем пункт Службы (для плагинов) в нашем контекстном меню.
theMenu.allowsContextMenuPlugIns=NO;

 

Как задать координаты для NSMenu

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

 

 

 

 

 

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *