简体   繁体   English

显示没有焦点的NSPopover

[英]Show NSPopover without Focus

I'm working on creating an IntelliSense style popover that shows the user who is typing into a text field what syntax is valid. 我正在创建一个IntelliSense样式的弹出框,该弹出框向正在显示文本字段的用户显示有效的语法。 Does anyone know how to show an NSPopover without giving it focus, so that the user can continue to type into the textField? 有谁知道如何显示NSPopover而不显示焦点,以便用户可以继续输入textField? The popover is triggered by controlTextDidChange: 弹出窗口由controlTextDidChange触发:

- (void) controlTextDidChange:(NSNotification *)obj
{

    NSTextField *field = [obj object];
    NSString *command = [field stringValue];

    if ([[command substringFromIndex: command.length - 1] isEqualToString: @"#"]){
        CompletionMenuController *completionController = [[CompletionMenuController alloc] initWithNibName: @"CompletionMenuController" bundle:[NSBundle mainBundle]];
        completionMenuPopover = [[NSPopoverInformation alloc] init];
        [completionMenuPopover setContentViewController: completionController];
        [completionMenuPopover setContentSize: completionController.view.frame.size];
        [completionMenuPopover setBehavior: NSPopoverBehaviorTransient];
        [completionMenuPopover setAppearance: NSPopoverAppearanceHUD];
        [completionMenuPopover showRelativeToRect:[_commandBar frame] ofView:_commandBar preferredEdge:NSMaxYEdge];
    }
}

This is a workaround, not exactly how I was trying to accomplish this, but it works. 这是一种解决方法,不完全是我尝试完成此操作的方法,但是它可以工作。 I save the cursor position in the textfield prior to opening the popover, then give the textfield first responder and change the cursor position back to where it was. 在打开弹出窗口之前,我将光标位置保存在文本字段中,然后为文本字段提供第一响应程序,并将光标位置更改回原来的位置。

if ([_commandBar stringValue].length > 0){
    NSString *command   = [_commandBar stringValue];
    NSRange range       = [[_commandBar currentEditor] selectedRange];

    //Open popover if command is being typed
    if ([[command substringFromIndex: command.length - 1] isEqualToString: @"#"]){
        CompletionMenuController *completionController = [[CompletionMenuController alloc] initWithNibName: @"CompletionMenuController" bundle:[NSBundle mainBundle]];

        //Configure and Open Popover
        if ([completionMenuPopover isShown]) [completionMenuPopover close];
        completionMenuPopover = [[NSPopover alloc] init];
        [completionMenuPopover setContentViewController: completionController];
        [completionMenuPopover setContentSize: completionController.view.frame.size];
        [completionMenuPopover setBehavior: NSPopoverBehaviorTransient];
        [completionMenuPopover setAppearance: NSPopoverAppearanceHUD];
        [completionMenuPopover setAnimates: NO];
        [completionMenuPopover showRelativeToRect:[_commandBar frame] ofView:_commandBar preferredEdge:NSMaxYEdge];

        //Reset Command Bar as First Responder
        [_commandBar becomeFirstResponder];
        [[_commandBar currentEditor] setSelectedRange: range];
    }
}

The auto closing of NSPopover seems to depend on detecting focus changes. NSPopover的自动关闭似乎取决于检测焦点变化。 That means it requires to set the first responder status to the popover if it is transient. 这意味着如果瞬变,则需要将第一响应者状态设置为弹出窗口。 Try NSPopoverBehaviorApplicationDefined and see if that solves the focus issue. 尝试使用NSPopoverBehaviorApplicationDefined ,看看是否可以解决焦点问题。 You have to take care to close the popover then, however. 但是,您必须注意关闭弹出窗口。 Explicitely setting back the focs to the edit control is however also a possible option, if there's no other way. 如果没有其他方法,则可以将foc显式设置回edit控件。 Showhing the popover will not change the visual appearance, so there will be no flicker for that short focus switch. 显示弹出框不会改变外观,因此该短焦点开关不会闪烁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM