Den*_*nis 8 cocoa nsstatusitem nsmenuitem
我使用popUpStatusItemMenu从NSStatusItem中弹出一个NSMenu.这些NSMenuItems显示了一堆不同的链接,每个链接都与setAction:连接到目标的openLink:方法.这种安排长期以来一直很好.用户从菜单中选择一个链接,然后openLink:方法处理它.
不幸的是,我最近决定尝试使用NSMenuItem的setView:方法来提供更好/更滑动的界面.基本上,我刚停止设置标题,创建了NSMenuItem,然后使用setView:来显示自定义视图.这非常有效,菜单项看起来很棒,我的自定义视图也会显示出来.
但是,当用户选择菜单项并释放鼠标时,操作将不再起作用(即,不会调用openLink:).如果我只是简单地注释掉setView:call,那么动作再次起作用(当然,菜单项是空白的,但动作正确执行).那么,我的第一个问题就是设置视图会破坏NSMenuItem的操作.
没问题,我想,我会通过在自定义视图中检测mouseUp事件并从那里调用我的action方法来修复它.我将此方法添加到自定义视图中:
- (void)mouseUp:(NSEvent *)theEvent {
NSLog(@"in mouseUp");
}
Run Code Online (Sandbox Code Playgroud)
没有骰子!永远不会调用此方法.
不过,我可以设置跟踪rects并接收mouseEntered:事件.我在mouseEntered例程中进行了一些测试,如下所示:
if ([[self window] ignoresMouseEvents]) { NSLog(@"ignoring mouse events"); }
else { NSLog(@"not ignoring mouse events"); }
if ([[self window] canBecomeKeyWindow]) { dNSLog((@"canBecomeKeyWindow")); }
else { NSLog(@"not canBecomeKeyWindow"); }
if ([[self window] isKeyWindow]) { dNSLog((@"isKeyWindow")); }
else { NSLog(@"not isKeyWindow"); }
Run Code Online (Sandbox Code Playgroud)
并得到以下回应:
not ignoring mouse events
canBecomeKeyWindow
not isKeyWindow
Run Code Online (Sandbox Code Playgroud)
这是问题吗?"not isKeyWindow"?据推测,这并不好,因为Apple的文档说"如果用户点击不在关键窗口中的视图,默认情况下窗口会被提前并变为密钥,但不会调度鼠标事件." 但必须有办法检测这些事件.怎么样?
添加:
[[self window] makeKeyWindow];
Run Code Online (Sandbox Code Playgroud)
尽管canBecomeKeyWindow是YES,但是没有效果.
Lot*_*har 12
将此方法添加到您的自定义NSView,它将适用于鼠标事件
- (void)mouseUp:(NSEvent*) event {
NSMenuItem* mitem = [self enclosingMenuItem];
NSMenu* m = [mitem menu];
[m cancelTracking];
[m performActionForItemAtIndex: [m indexOfItem: mitem]];
}
Run Code Online (Sandbox Code Playgroud)
但是我遇到了关键操作的问题,如果你解决了这个问题,也许你可以回答我的问题并帮助我一点点.
小智 9
将此添加到您的自定义视图,你应该没问题:
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
return YES;
}
Run Code Online (Sandbox Code Playgroud)
我将此方法添加到了自定义视图中,现在一切正常:
- (void)viewDidMoveToWindow {
[[self window] becomeKeyWindow];
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!