Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa LSUIElement与activateIgnoringOtherApps的行为不一致_Cocoa_Statusbar_Nsstatusitem - Fatal编程技术网

Cocoa LSUIElement与activateIgnoringOtherApps的行为不一致

Cocoa LSUIElement与activateIgnoringOtherApps的行为不一致,cocoa,statusbar,nsstatusitem,Cocoa,Statusbar,Nsstatusitem,具体而言,它在文本字段焦点方面的行为不一致 我有一个LSUIElement弹出一个状态菜单。在该菜单中有一个包含文本字段的视图。文本字段需要是可选择的——默认情况下不一定要选择,但以选择哪个为准 单击状态项时,它将触发 [NSApp activateIgnoringOtherApps:YES]; 它工作了大约一半时间。*另一半的状态菜单似乎把它自己放在“背景”中,即使点击它也不会让我把重点放在文本字段上。(我知道状态项click trigger正在触发b/c,上面有一个NSLog。) 这是苹果

具体而言,它在文本字段焦点方面的行为不一致

我有一个LSUIElement弹出一个状态菜单。在该菜单中有一个包含文本字段的视图。文本字段需要是可选择的——默认情况下不一定要选择,但以选择哪个为准

单击状态项时,它将触发

[NSApp activateIgnoringOtherApps:YES];

它工作了大约一半时间。*另一半的状态菜单似乎把它自己放在“背景”中,即使点击它也不会让我把重点放在文本字段上。(我知道状态项click trigger正在触发b/c,上面有一个NSLog。)

这是苹果处理这些状态项的一个错误,还是我在处理activateIgnoringOtherApps时出错了

*事实上,它似乎只是在另一个应用程序被激活后第一次失败。在那之后,它工作得很好

完整的代码片段:

-(void)statusItemClicked:(id)sender {
    //show the popup menu associated with the status item.
    [statusItem popUpStatusItemMenu:statusMenu];

    //activate *after* showing the popup menu to obtain focus for the text field.
    [NSApp activateIgnoringOtherApps:YES];

}

根据经验,我知道在弹出包含文本字段的菜单后,您必须调用
activateIgnoringOtherApps:
。因此,您需要按照以下顺序进行操作:

- (void)statusItemClicked:sender {
    [statusItem popUpStatusItemMenu:theMenu];
    [NSApp activateIgnoringOtherApps:YES]; // FYI, NSApp is shorthand for [NSApplication sharedApplication]
}

根据您所说的,您的应用程序似乎激活得太晚了,因此在您第一次单击该项目时它不会被激活,但在随后的单击中它已经被激活。

最终找到了解决方法

不要在单击处理程序中弹出菜单,而是激活应用程序,然后安排一个NSTimer,无延迟地弹出菜单:

-(void)pop:(NSTimer *)timer {
    [statusItem popUpStatusItemMenu:theMenu];
}

-(void)statusItemClicked:sender {
    [NSApp activateIgnoringOtherApps:YES];
    [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(pop:) userInfo:nil repeats:NO];
}

pop:
在下一帧被调用,因此延迟是不可察觉的,但足够长的时间
activateIgnoringOtherApps:
在同一帧中弹出菜单时执行阻止其正常工作的操作。

它肯定激活得太晚了,但代码已经按照您的建议进行了结构化。在状态菜单被取消之前,似乎不会调用activate方法(NSLog测试似乎证明了这一点)。我不明白为什么会发生这种情况。
activateIgnoringOtherApps:
会在
popUpStatusItemMenu:
之后立即被调用,还是直到菜单被取消后该方法才会返回?您可以尝试设置一个断点并运行调试器来查看发生了什么。是的,使用断点,它肯定只有在菜单被取消后才会被调用。将我的代码添加到第一篇文章中,尽管它看起来几乎与您的建议完全相同。如果您颠倒这两行代码,它会起作用吗?如果在弹出菜单之前激活应用程序?显然,只有在菜单关闭后才激活应用程序对你没有任何好处,而且我想不出在菜单出现时会调用另一个钩子。反转它们仍然会使文本字段无法选择,并且在菜单关闭后会抛出一些错误。statusItemClicked在awakeFromNib中被设置为statusMenu的选择器——这可能是延迟的一部分吗?