关闭NSStatusItem的自定义窗口

时间:2011-07-22 06:32:37

标签: objective-c cocoa nswindow nsstatusitem

单击NSStatusItem时,我弹出一个自定义窗口。该代码基于MAAtachedwindow。一切都很好,但当用户点击其他状态栏项目或其他应用程序时,我无法找到解除窗口的方法。

这是我创建窗口的代码:

    statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:width] retain];

    //setup custom status menu view
    CGFloat height = [[NSStatusBar systemStatusBar] thickness];
    NSRect viewFrame = NSMakeRect(0.0f, 0.0f, width, height);
    statusMenuView = [[[_ISStatusMenuView alloc] initWithFrame:viewFrame] retain];
    statusMenuView.offset = aOffset;
    statusItem.view = statusMenuView;

    //setup the window to show when clicked
    NSRect contentRect = NSZeroRect;
    contentRect.size = aView.frame.size;
    statusMenuWindow = [[[NSWindow alloc] initWithContentRect:contentRect
                                   styleMask:NSBorderlessWindowMask
                                     backing:NSBackingStoreBuffered 
                                       defer:NO] retain];

    [statusMenuWindow setLevel:NSPopUpMenuWindowLevel];
    [statusMenuWindow setBackgroundColor:[NSColor clearColor]];
    [statusMenuWindow setMovableByWindowBackground:NO];
    [statusMenuWindow setExcludedFromWindowsMenu:YES];
    [statusMenuWindow setOpaque:NO];
    [statusMenuWindow setHasShadow:NO];
    [statusMenuWindow useOptimizedDrawing:YES];
    [[statusMenuWindow contentView] addSubview:aView];
    [statusMenuWindow setDelegate:self];

    statusMenuView.statusMenuWindow = statusMenuWindow;

以下是我如何展示窗口:

- (void)centerView{
    NSRect menuFrame = self.window.frame;
    NSRect windowFrame = self.statusMenuWindow.frame;
    NSPoint menuPoint = NSMakePoint(NSMidX(menuFrame), NSMinY(menuFrame));
    menuPoint.x -= windowFrame.size.width*0.5f;
    menuPoint.y -= windowFrame.size.height+self.offset;
    [self.statusMenuWindow setFrameOrigin:menuPoint];
    [self.statusMenuWindow makeKeyAndOrderFront:self];
}

我希望windowDidResignKey委托方法可以解决这个问题,但是这种配置并不适用。代表正在工作,因为windowDidMove确实在运行。

- (void)windowDidResignKey:(NSNotification *)notification{
    NSLog(@"windowDidResignKey");
    [statusMenuView hideView];
}

- (void)windowDidResignMain:(NSNotification *)notification{
    NSLog(@"windowDidResignMain");
}

- (void)windowDidMove:(NSNotification *)notification{
    NSLog(@"windowDidMove");
}

回顾一下,当用户点击其他任何东西时,如何隐藏我的自定义窗口,标准状态栏菜​​单的工作方式是什么?

修改的 在查看Popup示例后,我唯一遗漏的是我必须继承NSPanel并使其成为关键窗口。

@interface Panel : NSPanel
@end

@implementation Panel

- (BOOL)canBecomeKeyWindow{
    return YES;
}

@end

1 个答案:

答案 0 :(得分:4)

您需要确保您的窗口可以成为关键窗口,并在调用密钥时调用窗口的orderOut:方法。您应该使用自定义的NSWindowController,如果您还没有,在这种情况下,您只需调用其“关闭”方法来关闭您的窗口。

我建议你不要发布一堆代码,而是看看这个最近发布的将窗口附加到状态项的优秀示例: Shpakovski Popup Window Example