Met*_*ble 6 macos cocoa objective-c nsstatusitem osx-yosemite
实际上所有的NSStatusItem已经被弃用了10.10并且底层的行为NSStatusBarButton似乎令人困惑.
目前我正在开发一个菜单栏应用程序.当用户单击应用程序的菜单栏图标时,我的应用程序委托中的方法通过target-action调用,该方法显示NSPopover(或者如果已经可见则关闭它)并包含一些信息.
通常情况下,如果您使用NSStatusItem关联NSMenu,当用户单击菜单栏图标时图标仍然以蓝色突出显示为蓝色,直到菜单关闭.同样,单击系统音量图标会弹出滑块并将其图标突出显示为蓝色,直到包含滑块的视图消失.
但是,由于我是打开NSPopover的人,系统会在鼠标按下时突出显示蓝色图标,然后在调用方法后将其返回到正常状态.意思是我在循环中似乎没有什么可以保持高亮.我希望图标继续在鼠标上突出显示,并且只在我告诉它时才恢复正常(即,当我关闭我的弹出框时.)
我不知道该怎么做.我试过用了
[self.statusItem.button setHighlighted: YES];
//or [self.statusItem.button highlight: YES];
Run Code Online (Sandbox Code Playgroud)
当我在我的app delegate中收到鼠标注册事件并打开popover时.问题是系统仍然有它,显然,从早期鼠标向下突出显示此帧/循环,并在我将其设置为突出显示后立即将其设置为由于鼠标向上而不突出显示.我可以通过将其封装在一个方法中并在一瞬间使用计时器或延迟选择器运行该方法来解决这个问题.这允许我保持图标突出显示但引入闪烁; 当鼠标向下移动时,图标会自动突出显示,因为鼠标向上移动它会突出显示一帧,然后我的方法重新突出显示它.
我还想也许我可以使用弃用setHighlightMode:并将其设置NO为阻止图标在点击时自动突出显示,然后使用setHighlighted: / highlighted:手动设置但不起作用.同样,我想也许这也可行:
NSButtonCell* cell = (NSButtonCell*)self.statusItem.button.cell;
cell.highlightsBy = NSNoCellMask;
Run Code Online (Sandbox Code Playgroud)
但无论点击它是否会自动突出显示图标,并在调用方法后立即将鼠标高亮显示在鼠标上.
基本上:
- 不希望的自动突出显示行为会
NSStatusBarButton干扰手动设置高亮状态,除非我延迟手动设置它会引入短暂的闪烁.- 似乎唯一成功禁用此自动行为的是弃用
setHighlightMode:,但这似乎可以防止所有突出显示,无论是否手动.- 唯一的解决方法似乎是向NSButtonCell添加一个子视图,为鼠标添加一个事件监听器,然后按照此处设置superview的高亮状态: NSStatusBarButton保持突出显示, 但我认为有一个更简单的方法只是...完全禁用自动突出显示.
tl; dr:有没有办法让我轻松地完全控制何时何时没有突出显示我的菜单栏图标,这样我可以在显示NSPopover时自然突出显示?
我最后通过不设置NSStatusItem动作选择器属性来解决这个问题.相反,我用NSEvent的addLocalMonitorForEventsMatchingMask:handler:.在处理程序块中,我检查它event.locationInWindow是否在我的状态项中.bounds.如果是这样,我发送.action手动的消息,然后返回nil以防止事件被传递.如果它不在状态图标的范围内,则返回,event以便正常传递.在我的点击处理方法中,我[self.statusItem.button highlight: YES/NO]在显示/关闭弹出窗口时使用.
TL; DR:
在 applicationDidFinishLaunching:
__block AppDelegate* appDelegate = self;
[NSEvent addLocalMonitorForEventsMatchingMask: NSEventMaskFromType(NSLeftMouseDown) handler:^NSEvent* (NSEvent* event){
if (NSPointInRect(event.locationInWindow, appDelegate.statusItem.button.bounds)){
[appDelegate clickedMenuBarIcon: event];
return nil;
}
return event;
}];
Run Code Online (Sandbox Code Playgroud)
在clickedMenuBarIcon:我可以再设定高的状态.由于我nil在处理程序块中返回,因此阻止事件被传递,因此自动突出显示永远不会发生,我可以手动执行.
如果有任何与此相关的错误,我会感激任何建议.