Objective c 从NSB按钮弹出菜单实现
我该怎么做呢 我在想Objective c 从NSB按钮弹出菜单实现,objective-c,macos,cocoa,Objective C,Macos,Cocoa,我该怎么做呢 我在想 [NSMenu popUpContextMenu:menu withEvent:event forView:(NSButton *)sender]; 是的 按钮式动作呼叫 [NSMenu popUpContextMenu:menu withEvent:event forView:(NSButton *)sender]; 在哪里 菜单:要显示的菜单 发件人:您单击的按钮 事件:创建一个新的n事件 创建新的NSEvent时,指定要显示弹出菜单的位置。在操作调用上使用上下
[NSMenu popUpContextMenu:menu withEvent:event forView:(NSButton *)sender];
是的
按钮式动作呼叫
[NSMenu popUpContextMenu:menu withEvent:event forView:(NSButton *)sender];
在哪里
:要显示的菜单菜单
:您单击的按钮发件人
:创建一个新的事件
n事件
创建新的
NSEvent
时,指定要显示弹出菜单的位置。在操作调用上使用上下文菜单不是一个好方法,因为菜单直到鼠标点击后才会显示-您不会获得按住并拖动菜单行为。Apple的ButtonMaddess示例展示了如何在NSButton的子类中真正做到这一点,请参见DropDownButton
总结该子类:创建一个NSPopUpButtonCell,pullsDown设置为YES&preferredEdge设置为NSMaxYEdge,复制菜单添加一个空白的顶部项,并将其设置为该单元格的菜单,鼠标向下调用[thePopUpCell PerformicClickWithFrame:self.bounds inView:self]设置self.needsDisplay正如我所评论的,我发现ButtonMaddess示例并不完美。 我的实现似乎工作得更好。在鼠标按下时显示菜单,按钮始终保持按下状态,可以指定菜单位置,菜单将被取消,而不会出现后续的虚假显示 老实说,在大多数情况下,按钮是一个更好的选择。我之所以使用这段代码,主要是因为有一个用于按钮和弹出窗口的类很方便,而且菜单不包含弹出控件图像和标题。我从一个单独的nib加载菜单,并根据需要在应用程序的其他地方重复使用它 请注意,添加对popover以及菜单的额外支持是很简单的
NSButton subclass:
- (void)mouseDown:(NSEvent *)theEvent {
// if a menu is defined let the cell handle its display
if (self.menu) {
if ([theEvent type] == NSLeftMouseDown) {
[[self cell] setMenu:[self menu]];
} else {
[[self cell] setMenu:nil];
}
}
[super mouseDown:theEvent];
}
NSButtonCell subclass:
- (BOOL)trackMouse:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp
{
// if menu defined show on left mouse
if ([event type] == NSLeftMouseDown && [self menu]) {
NSPoint result = [controlView convertPoint:NSMakePoint(NSMidX(cellFrame), NSMidY(cellFrame)) toView:nil];
NSEvent *newEvent = [NSEvent mouseEventWithType: [event type]
location: result
modifierFlags: [event modifierFlags]
timestamp: [event timestamp]
windowNumber: [event windowNumber]
context: [event context]
eventNumber: [event eventNumber]
clickCount: [event clickCount]
pressure: [event pressure]];
// need to generate a new event otherwise selection of button
// after menu display fails
[NSMenu popUpContextMenu:[self menu] withEvent:newEvent forView:controlView];
return YES;
}
return [super trackMouse:event inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp];
}
最近,我试图实现它,我想到了一个更简单的解决方案
-(IBAction)buttonClick:(id)sender {
NSButton * b = (NSButton*)sender;
NSPoint l = [ self.window convertBaseToScreen:b.frame.origin ];
[ self.menu popUpMenuPositioningItem:nil atLocation:l inView:nil ];
}
更新
convertBaseToScreen
从10.7开始不推荐使用,请按以下方式使用convertRectToScreen
:
NSPoint l = [self.window convertRectToScreen:b.frame].origin;
公认答案的快速版本
@IBAction func actionOccurred(sender: NSButton) {
if let event = NSApplication.sharedApplication().currentEvent {
NSMenu.popUpContextMenu(sender.menu!, withEvent: event, forView: sender)
}
}
最新答案 将NSMenu添加到故事板中的NSViewController,如图所示 连接插座 右键单击故事板中的按钮,并将菜单出口连接到我们刚刚添加到故事板的菜单(图像中箭头指向的位置) 添加IBAction 你喜欢那样做
-(IBAction)onClickSourceAdd:(id)sender {
NSMenu *mainMenu = [NSApp mainMenu];
NSMenu *sourceMenu = [[mainMenu itemAtIndex:2] submenu];
NSMenu *addMenu = [[sourceMenu itemAtIndex:0] submenu];
[NSMenu popUpContextMenu:addMenu
withEvent:[NSApp currentEvent]
forView:(NSButton *)sender];
}
试过了,但是“弹出”菜单有点到处都是。我希望它出现在按钮的正下方(例如,像谷歌Chrome中的“新标签”、“新窗口”等菜单),但这一个也出现在按钮下方。。。高…耶。如上所述,您可以在创建事件时指定弹出菜单的位置(需要显示的位置)。您可以对事件使用[[NSApplication sharedApplication]currentEvent]。[self.myButton sendActionOn:NSLeftMouseDownMask]将在鼠标按下时触发此操作。我建议
-[NSMenu popup:…]
而不是类方法。这样,即使您使用键盘快捷键,它也将相对于您的按钮定位。在10.8上,至少DropDownButton代码有缺陷。要突出显示该问题,请构建ButtonMaddess示例并单击下拉按钮。菜单将显示-不要选择项目。现在单击单选按钮2-菜单隐藏,但未选择单选项。因此,再次单击,菜单将再次显示。另一个点击和隐藏。为什么你需要添加空白项目?我很感激您这么做(未能添加它会截断菜单),但我无法找出为什么ConvertBaseToScreen会被弃用,因为10_7带有故事板(在ViewController中)它似乎不起作用。我尝试了,但没有成功:NSPoint point=[[self.view window]convertDirectToScreen:((NSButton*)sender.frame.)代码>一些想法?@Joannes检查您是否已正确设置所有,即您的操作已连接并正在被调用,self.menu不是nil,self.view.window不是nil。你得到了什么价值(点)?对我来说很有用。我发现我可以直接在单元格上设置菜单,而不需要对按钮进行子类化。我是不是遗漏了什么原因,这会成为一个问题?
-(IBAction)onClickSourceAdd:(id)sender {
NSMenu *mainMenu = [NSApp mainMenu];
NSMenu *sourceMenu = [[mainMenu itemAtIndex:2] submenu];
NSMenu *addMenu = [[sourceMenu itemAtIndex:0] submenu];
[NSMenu popUpContextMenu:addMenu
withEvent:[NSApp currentEvent]
forView:(NSButton *)sender];
}