1

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

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

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

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

4

1 回答 1

2

这行得通。我通过观察firstResponder父窗口的属性来做到这一点。如果令牌字段或其包含的任何NSResponders成为第一响应者,则显示弹出框。

@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
于 2012-09-02T07:06:47.563 回答