NSNotification addObserver 选择器无法在 window 上打开 NSBeginAlertSheet sheet
NSNotification addObserver selector could not open a NSBeginAlertSheet sheet on window
我有两个不同的 window 控制器。第一个是自定义面板 window 控制器,另一个是主 window 控制器。在面板 window 中有一个面板 window 并且该面板上有按钮。单击这些按钮后,我将发布如下通知:
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];
}
现在,在我的主 window 控制器中,我试图在 NSNotificationCenter
的 addObserver
的 selector
中打开一个 NSBeginAlertSheet
。以下是我的主要 window 控制器的 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.");
}
}
}
当用户单击面板上的“否”按钮时,应显示 window 上的警告。但从未显示警报。我还尝试了 [NSApp keyWindow]
和 [NSApp mainWindow]
而不是 [[self view] window]
。
而且,如果我 运行 警报独立于 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
这有点难说,但我最好的猜测是,在 okButtonClicked: 函数中对通知做出反应的对象没有对您的 window 的(有效)引用.然后,警报不知道要显示什么 window。
如果您可以在通知对象中发送对您的 window 的引用,那么您应该能够获得在您想要的 window 上显示的警报。
示例代码:
[[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.");
}
这适用于我的测试项目。
问题不在于通知,而是导致问题的面板:
我在主 window 控制器中打开面板:
[[self window] beginSheet:self.panelClass.panel completionHandler:nil];
而面板的关闭动作写在面板window控制器中。由于这个原因,在主 window.
上加载/卸载自定义面板后,没有显示 NSBeginAlertSheet
因此将以下代码从面板 window 控制器移动到主 window 控制器解决了问题:
[[self window] endSheet:self.panelClass.panel returnCode:NSModalResponseCancel];
[self.panelClass.panel orderOut:self];
我有两个不同的 window 控制器。第一个是自定义面板 window 控制器,另一个是主 window 控制器。在面板 window 中有一个面板 window 并且该面板上有按钮。单击这些按钮后,我将发布如下通知:
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];
}
现在,在我的主 window 控制器中,我试图在 NSNotificationCenter
的 addObserver
的 selector
中打开一个 NSBeginAlertSheet
。以下是我的主要 window 控制器的 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.");
}
}
}
当用户单击面板上的“否”按钮时,应显示 window 上的警告。但从未显示警报。我还尝试了 [NSApp keyWindow]
和 [NSApp mainWindow]
而不是 [[self view] window]
。
而且,如果我 运行 警报独立于 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
这有点难说,但我最好的猜测是,在 okButtonClicked: 函数中对通知做出反应的对象没有对您的 window 的(有效)引用.然后,警报不知道要显示什么 window。
如果您可以在通知对象中发送对您的 window 的引用,那么您应该能够获得在您想要的 window 上显示的警报。
示例代码:
[[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.");
}
这适用于我的测试项目。
问题不在于通知,而是导致问题的面板: 我在主 window 控制器中打开面板:
[[self window] beginSheet:self.panelClass.panel completionHandler:nil];
而面板的关闭动作写在面板window控制器中。由于这个原因,在主 window.
上加载/卸载自定义面板后,没有显示NSBeginAlertSheet
因此将以下代码从面板 window 控制器移动到主 window 控制器解决了问题:
[[self window] endSheet:self.panelClass.panel returnCode:NSModalResponseCancel];
[self.panelClass.panel orderOut:self];