当NSTokenField成为第一响应者时,如何执行操作(显示弹出窗口)?

时间:2012-09-02 05:19:29

标签: objective-c cocoa nstokenfield

一旦控件获得焦点,我正试图将NSTokenField子类化为显示NSPopover或带有一些选项的菜单。不幸的是,经过几天的尝试,我开始认为这是不可能的。

这是我到目前为止所尝试的内容:

  • -textDidBeginEditing-controlTextDidBeginEditing没用,因为只有在用户输入第一个字母后才会调用它们。我需要在焦点上被解雇的东西。
  • 覆盖-becomeFirstResponder-resignFirstResponder以显示和隐藏菜单或弹出窗口也没用。令牌字段显然将第一个响应者状态传递给私人视图(NSTokenFieldView),因此在-resignFirsttResponder关闭菜单或立即弹出后立即调用-becomeFirstReponder
  • 在关闭-currentEditor中的菜单之前,我尝试查看-resignFirstResponder的值。当控件处于编辑模式时,-currentEditor应该是非零的,但不幸的是,只有在调用令牌字段中的-resignFirstResponder之后才设置其值,并且菜单立即再次关闭。
  • 我尝试了对NSTokenFieldCell进行子类化并覆盖其-editWithFrame:-selectWithFrame:方法,但我的自定义NSTokenFieldCell的令牌字段根本没有显示,并且没有报告任何错误或异常

有关如何做到这一点的任何想法?有人做过吗?

1 个答案:

答案 0 :(得分:2)

这很有效。我通过观察父窗口的firstResponder属性来做到这一点。如果令牌字段或其包含的NSResponder s 中的任何一个成为第一响应者,则显示弹出窗口。

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    [ self.window addObserver:self forKeyPath:@"firstResponder" options:NSKeyValueObservingOptionNew context:nil ] ;
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ( object == self.window && [ keyPath isEqualToString:@"firstResponder" ] )
    {
        NSResponder * responder = [ change valueForKey:NSKeyValueChangeNewKey ] ;

        while ( NULL != responder )
        {
            if ( responder == self.tokenField )
            {
                // show popover (if not showing)
                NSLog(@"Show popover!\n") ;
                return ;
            }
            responder = responder.nextResponder ;
        }

        NSLog(@"Hide popover!\n") ;
    }
    else
    {
        [ super observeValueForKeyPath:keyPath ofObject:object change:change context:context ] ;
    }
}

@end