【问题标题】:control NSSlider with arrows on NSMenu for a NSStatusItem- Objective-C/Cocoa在 NSMenu 上使用 NSStatusItem-Objective-C/Cocoa 的箭头控制 NSSlider
【发布时间】:2011-10-17 12:11:57
【问题描述】:

我想创建一个带有垂直滑块的状态项,就像 Apple 提供的声音控制一样。我的问题是:如何让它对上/下箭头键做出反应,就像声音菜单中的滑块一样?

我试图创建一个 NSSlider 子类,当按键被按下时会增加/减少它的值(见下文),但我需要让它成为第一响应者。为了使它成为第一响应者,我将主类设置为这个菜单的代表并添加了这个方法:

- (void)menuWillOpen: (NSMenu*)menu
{
    if (menu == statusBarMenu) {        
        [THE_WINDOW_THAT_CONTAINS_THE_SLIDER makeFirstResponder: slider];
}

我应该调用哪个窗口?我应该以其他方式这样做吗?你会怎么做呢?

滑块子类:

#import <AppKit/AppKit.h>

@interface KeyRespondingSlider : NSSlider

@end

@implementation KeyRespondingSlider

- (BOOL)canBecomeKeyView
{
    return YES;
}
- (BOOL)acceptsFirstResponder
{
    return YES;
}

- (void)keyDown: (NSEvent*)theEvent
{
    unsigned short keyCode = [theEvent keyCode];
    if (keyCode == 126) { // up-arrow
        [self setDoubleValue: [self doubleValue] + kChange];
    }
    else if (keyCode == 125) { // down-arrow
        [self setDoubleValue: [self doubleValue] - kChange];
    }
}

@end

我已经对其进行了测试,当它是具有正常 NSWindow 的第一响应者时,它可以工作。我只是不能用状态栏项目中的菜单来做到这一点。

【问题讨论】:

    标签: objective-c cocoa nsmenu nsstatusitem nsslider


    【解决方案1】:

    我想通了。 Apple 使用名为 NSCarbonMenuWindow 的 NSWindow 子类来实现菜单。所以我得到了 menuWillOpen: 消息,我等待菜单打开,我得到最后一个窗口(刚刚创建的那个 - 菜单窗口),并将滑块设置为 firstResponder。现在一切正常!

    - (void)menuWillOpen: (NSMenu*)menu
    {
        if (menu == statusBarMenu) {
            [NSThread detachNewThreadSelector: @selector(threadedMenuWillOpen) toTarget: self withObject: nil];
        }
    }
    
    - (void)threadedMenuWillOpen
    {
        [NSThread sleepForTimeInterval: 0.1];
    
        NSArray* windows = [NSApp windows];
        NSWindow* menuWindow = [windows lastObject]; // The last window is the one I want because it has just been created
    
        if ([[menuWindow className] isEqualToString: @"NSCarbonMenuWindow"]) {
            [menuWindow makeFirstResponder: bSlider];
        }    
    }
    

    【讨论】:

      【解决方案2】:
      - (void)keyDown: (NSEvent*)theEvent
      {
          unsigned short keyCode = [theEvent keyCode];
          if (keyCode == 126) { // up-arrow
              [[NSNotificationCenter defaultCenter] postNotificationName:@"upArrow" object:nil];
          }
          else if (keyCode == 125) { // down-arrow
              [[NSNotificationCenter defaultCenter] postNotificationName:@"DownArrow" object:nil];
          } else
          {
              [super keyDown:theEvent];
          }
      }
      

      【讨论】:

      • 添加 [super keyDown:theEvent] 否则,如果您有多个滑块,您将无法通过滑块进行切换
      猜你喜欢
      • 1970-01-01
      • 2012-03-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      相关资源
      最近更新 更多