当尝试在Xib中显示第二个窗口时,模态会话需要模态窗口错误

时间:2014-02-07 15:46:05

标签: objective-c cocoa nswindow nswindowcontroller

我有一个带有两个NSWindows的Xib和一个继承自NSWindowController的Controller。第一个窗口连接到窗口IBOutlet。第二个连接到新的IBOutlet mySecondWindow。

然后我使用

创建控制器
myController = [[MySheetController alloc] initWithWindowNibName:@"MySheet"];

然后我在这个控制器上调用一个方法,它将第一个窗口显示为Sheet:

[NSApp beginSheet:self.window modalForWindow:mainWindow modalDelegate:self didEndSelector: @selector(didEndSheet:returnCode:contextInfo:) contextInfo: nil];

这可以按预期工作。但是,如果我现在用我的第二个窗口运行调用,它将给出错误“模态会话需要模态窗口”。当我调试时,我可以看到mySecondWindow IBOutlet是零。

[NSApp beginSheet:mySecondWindow modalForWindow:mainWindow modalDelegate:self didEndSelector: @selector(didEndSheet:returnCode:contextInfo:) contextInfo: nil];

当我现在将窗口IBOutlet更改为第二个窗口时,它将正常工作。

那么我需要做些什么才能显示第二张纸。为什么它只在连接到IBOutlet窗口时加载? initWithWindowNibName调用不应该在Xib中创建所有窗口吗?

编辑:所以我做了一个最小的例子:

AppDelegate.h:

#import <Cocoa/Cocoa.h>
#import "MyWindowController.h"

@interface AppDelegate : NSObject <NSApplicationDelegate>
{
    MyWindowController* mwc;
}

@property (assign) IBOutlet NSWindow *window;

@end

AppDelegate.m:

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    mwc = [[MyWindowController alloc] initWithWindowNibName:@"Window"];    

    // 1. the following works:
    [NSApp beginSheet:mwc.window modalForWindow:self.window modalDelegate: self didEndSelector: @selector(didEndSheet:returnCode:contextInfo:) contextInfo: nil];

    // 2. this one doesn't
    [NSApp beginSheet:mwc.mySecondWindow modalForWindow:self.window modalDelegate: self didEndSelector: @selector(didEndSheet:returnCode:contextInfo:) contextInfo: nil];
}

- (void)didEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
    [sheet orderOut:self];
}

@end

MyWindowController.h:

#import <Cocoa/Cocoa.h>

@interface MyWindowController : NSWindowController
@property (strong) IBOutlet NSPanel *mySecondWindow;

@end

MyWindowController.m:

#import "MyWindowController.h"

@implementation MyWindowController

- (id)initWithWindow:(NSWindow *)window
{
    self = [super initWithWindow:window];
    if (self) {
        // Initialization code here.
    }
    return self;
}

- (void)windowDidLoad
{
    [super windowDidLoad];

}

@end

然后我在其中制作了一个带有NSWindow的新Xib和第二个NSPanel。我将File的Owner的类设置为MyWindowControlller类。然后我将NSWindow连接到文件所有者的窗口属性,我创建了一个新的IBOutlet并将NSPanel连接到它。对于这两个窗口,我取消选择“在发射时可见”。

运行第一个beginSheet调用时,所有操作都按预期工作。但是,当我用mySecondWindow运行第二行时,它给了我一个:

***断言失败 - [NSApplication _commonBeginModalSessionForWindow:relativeToWindow:modalDelegate:didEndSelector:contextInfo:],/ SourceCache / AppKit / AppKit-1187.40 / AppKit.subproj / NSApplication.m:3920

模态会话需要模态窗口

我得到了一个解决方案:

- (id)initWithWindowNibName:(NSString *)windowNibName
{
    self = [super initWithWindowNibName:windowNibName];
    if (self) {
        [self window];
    }
    return self;
}

我需要打电话给self.window一次,然后一切正常。访问窗口属性时,窗口将加载延迟。这就是原因。

我想有一种更好的方法来强制它加载所有窗口,所以我可以先使用第二个窗口,但这很有效。

请参阅此处的评论:How show sheet loaded from xib? (MacOSx)

0 个答案:

没有答案