【问题标题】:NSClosableWindowMask dialog acting strangeNSClosableWindowMask 对话框表现得很奇怪
【发布时间】:2013-12-10 10:26:40
【问题描述】:

我有一个 Safari 浏览器插件,我想在其中打开一个 NSWindow 来显示版权说明。虽然对话框中的 Ok 按钮关闭了对话框的窗口,并且工作正常,但当我单击左上角的红色关闭窗口“x”时,它也会关闭窗口,但它是父窗口(整个浏览器选项卡,我已在其中运行插件),仍然处于禁用状态,就好像在某处仍然打开了一个模态窗口。

我什至尝试将一个新的选择器附加到窗口关闭通知,它运行与确定按钮相同的代码,但仍然无法正常工作。

以下是代码的相关部分:

- (void) closeBox
{
    // called when the Ok button pressed
    [NSApp abortModal];

}

- (void)closeClicked:(NSNotification *)notification
{
    // called when the close window 'x' button pressed
    NSLog(@"Closed");
    [NSApp abortModal];
}


- (void) openBox
{
    NSRect frame = NSMakeRect(0, 0, 300, 250);
     mwin  = [[[NSWindow alloc] initWithContentRect:frame
                                     styleMask:NSClosableWindowMask |NSTitledWindowMask
                                       backing:NSBackingStoreBuffered
                                         defer:NO] autorelease];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(closeClicked:)
                                             name:NSWindowWillCloseNotification
                                           object:mwin];
    NSButton * bn;
    bn = [[[NSButton alloc] initWithFrame:NSMakeRect(10, 10, 100, 20) ] autorelease];

    [bn setButtonType:NSMomentaryPushInButton];
    [bn setTitle:@"Ok"];
    [bn setTarget:self];
    [bn setAction:@selector(closeBox)];

    [[mwin contentView] addSubview:bn];

    [NSApp runModalForWindow:mwin];   
}

【问题讨论】:

    标签: objective-c macos nswindow


    【解决方案1】:

    我已经修改了你的代码尝试如下:-

    - (void) closeBox
    {
        // called when the Ok button pressed
      //Commented this line 
     // [NSApp abortModal];
    
        [mwin performClose:mwin];// Modified this line 
    
    
    }
    
       //Modified below notification just comment the parameter
        - (void)closeClicked/*:(NSNotification *)notification*/
        {
    
        [NSApp abortModal];
    
    }
    
    
    - (void) openBox
    {
        NSRect frame = NSMakeRect(0, 0, 300, 250);
        mwin  = [[[[NSWindow alloc] initWithContentRect:frame
                                             styleMask:NSClosableWindowMask |NSTitledWindowMask
                                               backing:NSBackingStoreBuffered
                                                defer:NO]retain]autorelease];
      //Modified notification below    
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(closeClicked)
                                                     name:NSWindowWillCloseNotification
                                                   object:nil];
        NSButton * bn;
        bn = [[[NSButton alloc] initWithFrame:NSMakeRect(10, 10, 100, 20) ] autorelease];
    
        [bn setButtonType:NSMomentaryPushInButton];
        [bn setTitle:@"Ok"];
        [bn setTarget:self];
        [bn setAction:@selector(closeBox)];
    
        [[mwin contentView] addSubview:bn];
    
        [NSApp runModalForWindow:mwin];   
    }
    

    【讨论】:

    • 感谢您的回答,但不幸的是这并没有解决我的问题,症状还是一样:对话框消失后,我不能再点击了。无论如何,您在 closeBox() 中的修改毫无意义,当使用“x”关闭窗口时,根本不会调用它。你有什么别的想法吗?
    • @Mkoch,我已经修改了 closeClicked 方法,如果您需要评论通知参数,它将在您单击 x 按钮时调用。你也完全运行了我的代码吗??
    • 对我来说也可以正常工作。你观察到通知了吗??
    • 是的,确实调用了closeClicked,我只是在谈论closeBox方法。是的,我确实逐行复制并合并了整个代码。你能用我的原始代码重现这个问题吗?
    • 实际上在closeBox 中使用[mwin performClose:mwin] 而不是[NSApp abortModal] 如您所建议的那样,单击以前工作的“确定”按钮bn 时会导致我这边崩溃。
    【解决方案2】:

    经过几个小时的谷歌搜索,我发现其他人也有类似的问题,解决方案很简单:窗口对象被 NSNotificationCenter 的观察者保留。我所要做的就是移除观察者:

    - (void) closeClicked:(NSNotification *)notification
    {
    
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [NSApp abortModal];
    
        NSLog(@"Closed");
    
    }
    

    现在它可以正常工作了。

    【讨论】: