【问题标题】:NSNotification addObserver selector could not open a NSBeginAlertSheet sheet on windowNSNotification addObserver 选择器无法在窗口上打开 NSBeginAlertSheet 表
【发布时间】:2015-02-24 05:18:25
【问题描述】:

我有两个不同的窗口控制器。第一个是自定义面板窗口控制器,另一个是主窗口控制器。在面板窗口中有一个面板窗口,该面板上有按钮。单击这些按钮后,我将发布通知,例如:

In PanelWindowController:
    -(IBAction)okAndCancelButtonClicked:(id)sender
    {
        [self postNotification:sender];
    }

    -(void)postNotification:(id)sender
    {
        if([sender tag]!=2){
            [[self window]  endSheet:self.panel returnCode:NSModalResponseCancel];
            [self.panel orderOut:self];
        }
        NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:[sender tag]],@"value",nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"PanelButtonClickedNotification" object:self userInfo:dict];
    }

现在,在我的主窗口控制器中,我试图在 addObserverselectorNSNotificationCenter 中打开一个 NSBeginAlertSheet。以下是我的主窗口控制器的init 方法中的addObserver selector 声明:

MainWindowController

-(id) init{
..// some code here
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(okButtonClicked:) name:@"PanelButtonClickedNotification" object:[self panelClass]];
return self;
}

okButtonClicked 的实现如下:

- (void) okButtonClicked:(NSNotification*)notification
{
    if ([[notification object] isEqualTo:[self panelClass]])
    {
        if([[[notification userInfo] objectForKey:@"value"] integerValue] == 1)
        {
            // Yes Button in the Panel is clicked
        }
        else if([[[notification userInfo] objectForKey:@"value"] integerValue] == 0)
        {
            // No Button in the Panel is clicked
            NSBeginAlertSheet(@"Alert", @"Ok", nil, nil, [[self view] window], self,nil, nil,nil,@"Alert is being shown on window.");
        }

    }
}

当用户单击 Panel 上的 No 按钮时,应在窗口上显示警报。但从未显示警报。我还尝试了[NSApp keyWindow][NSApp mainWindow] 而不是[[self view] window]。 而且,如果我独立于窗口运行警报,则会显示:

NSAlert *alert = [[NSAlert alloc] init];
 [alert setMessageText:@"Alert"];
 [alert addButtonWithTitle:@"OK"];
 NSImage *icon=[NSImage imageNamed:@"warning.png"];
 [alert setIcon:icon];
 [alert runModal];

如果我在这里遗漏了什么,请告诉我。

在收到通知后调用的任何方法中都不会显示警报。 PFA 我的示例项目:https://www.dropbox.com/s/0xfe4bk17v9girj/PanelApplication.zip?dl=0

【问题讨论】:

    标签: objective-c cocoa nsnotificationcenter alerts


    【解决方案1】:

    这有点难说,但我最好的猜测是,在 okButtonClicked: 函数中对通知做出反应的对象没有对您的窗口的(有效)引用。然后,警报不知道要在哪个窗口显示。

    如果您可以在通知对象中发送对您的窗口的引用,那么您应该能够获得在您想要的窗口上显示的警报。

    示例代码:

    [[NSNotificationCenter defaultCenter] postNotificationName:@"PanelButtonClickedNotification" object:[self window]];
    

    还有:

    - (void) okButtonClicked:(NSNotification*)notification
    {   
       NSBeginAlertSheet(@"Alert", @"Ok", nil, nil, [notification object], self,nil, nil,nil,@"Alert is being shown on window.");
    }
    

    这适用于我的测试项目。

    【讨论】:

    • 我在发布通知时发送了一些userInfo。 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:[sender tag]],@"value",nil]; [[NSNotificationCenter defaultCenter] postNotificationName:@"PanelButtonClickedNotification" object:self userInfo:dict];所以我将无法发送window 作为通知对象。
    • 您可以将它添加到您正在创建和解析的字典中。当然只有当它存在/类知道窗口时。 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:[sender tag]],@"value",[self window],@"window", nil];然后检索它 [[notification userInfo] objectForKey:@"window"]
    • 在发布通知时无法传递[self window],因为它位于单独的窗口控制器中(在此仅存在一个面板窗口,其中有按钮,按下这些按钮时,通知被发送)。主窗口在另一个窗口控制器中,我在其中接收通知......同样,一旦面板在主窗口上打开并发送/接收通知......之后,我无法以任何其他方法打开 NSBeginAlertSheet。: (
    【解决方案2】:

    问题不在于通知,而是导致问题的面板: 我在主窗口控制器中打开面板:

    [[self window] beginSheet:self.panelClass.panel completionHandler:nil];

    并且面板的关闭动作写在Panel窗口控制器中。由于这个原因,在主窗口上加载/卸载自定义面板后,不会显示 NSBeginAlertSheet

    因此将以下代码从面板窗口控制器移动到主窗口控制器解决了这个问题:

    [[self window] endSheet:self.panelClass.panel returnCode:NSModalResponseCancel]; [self.panelClass.panel orderOut:self];

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      • 1970-01-01
      • 2016-04-28
      • 1970-01-01
      • 2018-10-31
      • 2011-08-04
      相关资源
      最近更新 更多