【问题标题】:Capturing "up" and "down" keys pressed in NSTextField捕获在 NSTextField 中按下的“向上”和“向下”键
【发布时间】:2011-07-11 09:30:03
【问题描述】:

我编写了一个“代理”Cocoa 应用程序,其中 TextField 位于状态图标的菜单中。图标菜单显示如下:


(来源:ifotos.pl

步进器将值递增或递减 5。文本字段的目的是按“向上”或“向下”键,实现与值递增或递减 5 相同的结果。

我发现下面的代码必须使用- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelectorNSControlTextEditingDelegate协议。

我目前遇到的问题是如何实现代码。我通常的做法是使用sth.delegate = self;。我试图寻找答案,但回复包括使用control:textView:...。即使经过进一步研究,我也无法学习如何使用委托方法。

提前谢谢你!

【问题讨论】:

    标签: objective-c cocoa nstextfield


    【解决方案1】:

    您需要创建一个对象来充当文本字段的委托。这可以在代码中完成,如果合适的话,可以在 Interface Builder 中完成。您可能已经有一个负责该字段和步进控制的控制器,所以这是一个不错的选择。这个委托对象是实现你提到的方法所需要的:

    - (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector
    

    每当要求文本字段的field editor* 执行NSResponder action messages 之一时,都会调用此方法。字段编辑器询问它的委托,即文本字段,它应该做什么,然后字段又询问它的委托,即您的对象。

    commandSelector 参数包含操作消息的名称。因此,您可以测试您感兴趣的消息(在这种情况下为moveUp:moveDown:)并拦截它们。您可以执行任何您喜欢的操作并阻止字段编辑器或文本字段对消息进行操作。

    - (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor 
      doCommandBySelector:(SEL)commandSelector {
        if( commandSelector == @selector(moveUp:) ){
            // Your increment code
            return YES;    // We handled this command; don't pass it on
        }
        if( commandSelector == @selector(moveDown:) ){
            // Your decrement code
            return YES;
        }
    
        return NO;    // Default handling of the command
    
    } 
    

    *简而言之,NSTextView 在字段处于活动状态时代表文本字段处理输入。

    【讨论】:

    • Radex,希望这比文档更容易理解;如果您需要澄清,请告诉我。
    • 是的,是的,是的!谢谢你。这比文档更容易理解。 Apple 的文档太混乱了,我什至没有想到它是 显而易见的 :)
    【解决方案2】:

    尝试像这样覆盖 NSResponder 消息:

    - (BOOL)performKeyEquivalent:(NSEvent *)theEvent{
        switch ([[theEvent charactersIgnoringModifiers] characterAtIndex:0]) {
            case NSUpArrowFunctionKey:
                // Increase by 5 here
                return YES;
                break;
            case NSDownArrowFunctionKey:;
                // Decrease by 5 here
                return YES;
                break;
            default:
                break;
        }
        return [super performKeyEquivalent:theEvent];
    }
    

    【讨论】:

    • 我发现了关于这个方法的一件奇怪的事情:performKeyEquivalent 并不局限于响应者链。任何实现这一点的视图都可以被调用,不管它是否有焦点,如果它返回 YES,它可以阻止当前的第一响应者接收到关键事件。如果您使用它来捕获 NSTextField 子类中的箭头键按下,首先检查它是否是当前的第一响应者: if ( [[self window] firstResponder] != self ) return [super performKeyEquivalent:event];
    【解决方案3】:

    如果你想捕获快捷方式,你也可以使用这样的代码:

    - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
    
    NSEvent *currentEvent = [[NSApplication sharedApplication]currentEvent];
    if ((currentEvent.modifierFlags & NSCommandKeyMask) && (currentEvent.keyCode == kVK_Return)) {  //command + enter to confirm
        //do what you want
        return YES;
    }
    return NO;
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-11
      • 2012-08-20
      • 1970-01-01
      • 2021-05-16
      • 2021-05-28
      • 1970-01-01
      • 2015-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多