NSPopover from NSMenuItem (Button)不接受鼠标事件



我想知道是否有人知道为什么一个NSPopover不响应鼠标事件(悬停,点击),当它从一个NSMenuItem在一个NSMenuItem里面的按钮打开。

这个问题有什么解决办法吗?

这是一个小示例视图控制器,它将一个NSMenu附加到它的视图上。菜单有一个按钮,在点击时打开弹出窗口,还有一些虚拟项目,它们只是在那里显示它们仍然接收鼠标事件,即使弹出窗口在它们上面:

@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];

NSMenu *menu = [NSMenu new];
/// Some Dummy Items to show that the popover doesn’t accept the mouse.
NSArray *dummyItems = @[@"item1", @"item2", @"item3"];
for (NSString *itemName in dummyItems) {
NSMenuItem *item = [NSMenuItem new];
item.title = itemName;
item.target = self;
item.action = @selector(doNothing:);
[menu addItem:item];
}

/// The button which presents the popover on click
NSMenuItem *item = [NSMenuItem new];
NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 30)];
button.target = self;
button.action = @selector(showPopover:);
button.title = @"Show Popover";
item.view = button;
[menu addItem:item];

[self.view setMenu:menu];
}
- (void)showPopover:(NSButton *)sender {
/// This popover does not receive the mouse events for some reason.
NSPopover *popover = [NSPopover new];
NSViewController *popoverVC = [NSViewController new];
NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 140, 25)];
button.title = @"I’m not clickable";
button.target = self;
button.action = @selector(showPopover:);
popoverVC.view = button;
[popover setContentViewController:popoverVC];
[popover showRelativeToRect:sender.frame ofView:sender.superview preferredEdge:NSMaxYEdge];
[button.window makeKeyWindow];   /// Does not help
[button.window becomeKeyWindow]; /// Does not help
}
- (void)doNothing:(id)sender {}
@end

有一个解决方案,但它可能并不有用,这取决于您想要做什么。我无法运行你发布的代码,但可以看到你添加了一个按钮到菜单和弹出窗口。问题似乎是用于显示弹出窗口的矩形。由于我不知道的原因,如果我们试图根据菜单项按钮的框架显示弹出窗口,则无法单击弹出窗口按钮。然而,如果弹出窗口显示是基于一个基于窗口内容视图的控件的框架,比如NSPopUpButton或者位于菜单附近的NSView的矩形,弹出窗口按钮变得可点击。从菜单栏中掉落的菜单带来了更多的挑战,因为缺少附近的矩形。这个演示可以在Xcode objc项目中通过删除已有的main来运行。M代码并复制/粘贴以下内容到其中。还需要删除已有的AppDelegate文件,以避免重复的符号。演示了使用NSView矩形和NSPopUpButton帧显示弹出窗口,这将使一个可点击弹窗的按钮。失败的代码将被REMmed out。

#import <Cocoa/Cocoa.h>
@interface PopoverController: NSViewController
@end
@implementation PopoverController
@end

@interface AppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
NSPopover *popover;
NSView *popoverView;
NSMenuItem *menuItem;
NSMenu *menu;
PopoverController *popoverController;
NSPopUpButton *pullDwn;
NSView *menuView;
}
- (void) showPopoverAction:(id)sender;
- (void) menuAction:(id)sender;
- (void) myBtnAction:(id)sender;
- (void) buildMenu;
- (void) buildWnd;
@end
@implementation AppDelegate

- (void) showPopoverAction:(id)sender {
// **** This works **** //
//[popover showRelativeToRect:pullDwn.bounds ofView:pullDwn preferredEdge:NSMaxXEdge];
[popover showRelativeToRect:menuView.bounds ofView:menuView preferredEdge:NSMaxXEdge];
// **** This doesn't **** //
//[popover showRelativeToRect:[menuItem.view bounds] ofView:menuItem.view preferredEdge:NSMaxXEdge];
}
- (void) myBtnAction: (id)sender {
NSBeep();
NSLog(@"Popover button hit.");
NSLog(@"===================");
}
- (void) menuAction: (id)sender {
[popover showRelativeToRect:pullDwn.bounds ofView:pullDwn preferredEdge:NSMaxXEdge];
}
- (void) buildMenu {
NSMenu *menubar = [NSMenu new];
NSMenuItem *menuBarItem = [NSMenuItem new];
[menubar addItem:menuBarItem];
[NSApp setMainMenu:menubar];
NSMenu *appMenu = [NSMenu new];
NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
[appMenu addItem:quitMenuItem];
[menuBarItem setSubmenu:appMenu];
}
- (void) buildWnd {
#define _wndW  500
#define _wndH  350
window = [[NSWindow alloc] initWithContentRect: NSMakeRect( 0, 0, _wndW, _wndH )
styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable
backing: NSBackingStoreBuffered defer: NO];
[window center];
[window setTitle: @"NSPopUpButton Menu"];
[window makeKeyAndOrderFront: nil];
// ******* Popover controller ********* //
popoverController = [[PopoverController alloc] init];
// **** Menu View **** //
menuView = [[NSView alloc]initWithFrame:NSMakeRect( 100, _wndH - 242, 130, 30 ) ];
[[window contentView] addSubview:menuView];
// ****** Pull-Down NSPopUpButton ******* //
// First array element (0) becomes the title
NSArray *menuItems = [NSArray arrayWithObjects: @"Pull-Down", @"Item 1", @"Item 2",@"Item 3",nil];
pullDwn = [[NSPopUpButton alloc] initWithFrame:NSMakeRect( 100, _wndH - 142, 130, 30 )];
menu = pullDwn.menu;
menuItem = [NSMenuItem new];
NSButton *myBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 30, 30, 95, 30 )];
[myBtn setBezelStyle:NSBezelStyleRounded ];
[myBtn setTitle: @"Popover"];
[myBtn setAction: @selector (showPopoverAction:)];
menuItem.view = myBtn;
[pullDwn setPullsDown:YES];
[pullDwn addItemsWithTitles:menuItems];
[pullDwn setTarget:self];
[pullDwn setAction:@selector(menuAction:)];
[menu addItem:menuItem];
[[window contentView]addSubview:pullDwn];
// **** NSPopover **** //
popover = [[NSPopover alloc] init];
[popover setContentViewController:popoverController];
[popover setContentSize:NSMakeSize(150, 100)];
//[popover setBehavior:NSPopoverBehaviorTransient];
[popover setBehavior:NSPopoverBehaviorSemitransient];
//[popover setBehavior:NSPopoverBehaviorApplicationDefined];
[popover setAnimates: YES];
[popover setDelegate: self];

// ****** Popover view ****** //
popoverView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 150, 100)];
//******* Popover text field ******* //
NSTextField *ef = [[NSTextField alloc] initWithFrame:NSMakeRect( 20, 20, 110, 24 )];
[ef setStringValue:@"EditFld"];
[ef setAlignment:NSTextAlignmentCenter];
[ef setDrawsBackground:NO];
[popoverView addSubview:ef];
// **** Popover Button **** //
NSButton *popoverBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 20, 50, 95, 24 )];
[popoverBtn setBezelStyle:NSBezelStyleRounded ];
[popoverBtn setTitle: @"Push me"];
popoverBtn.target = self;
popoverBtn.action = @selector(myBtnAction:);
[popoverView addSubview: popoverBtn];
[popoverController setView:popoverView];
// ***** Quit btn ***** //
NSButton *quitBtn = [[NSButton alloc]initWithFrame:NSMakeRect( _wndW - 50, 5, 40, 40 )];
[quitBtn setBezelStyle:NSBezelStyleCircular ];
[quitBtn setTitle: @"Q" ];
[quitBtn setAutoresizingMask: NSViewMinXMargin];
[quitBtn setAction:@selector(terminate:)];
[[window contentView] addSubview: quitBtn];
}
- (void) applicationWillFinishLaunching: (NSNotification *)notification {
[self buildMenu];
[self buildWnd];
}
- (void) applicationDidFinishLaunching: (NSNotification *)notification {
}
@end
int main () {
NSApplication *application = [NSApplication sharedApplication];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application run];
return 0;
}

最新更新