NSWindowController не скрывает свое окно при инициализации?

#objective-c #nswindow #nsdocument #nswindowcontroller

#objective-c #nswindow #nsdocument #nswindowcontroller

Вопрос:

У меня есть подкласс NSDocument с двумя NSWindowControllers, соответствующими двум разным xib.

Следуя руководству по применению на основе документа, я добавил следующее в свою реализацию document.m

 - (void)makeWindowControllers 
{
    NSLog(@"in MakeWindowControllers");

    MainWindowController *mainWindowController = [[MainWindowController alloc] init];
    [mainWindowController autorelease];
    [self addWindowController:mainWindowController];

    csvWindowController = [[CSVWindowController alloc] init];
    [csvWindowController autorelease];
    [self addWindowController:csvWindowController];        
}
  

Проблема в том, что я хочу, чтобы второй оконный контроллер csvWindowController изначально скрывал свое окно, я покажу тот же экземпляр окна позже. Для этого я написал:

 @implementation CSVWindowController


- (id) init {

    if ( ! (self = [super initWithWindowNibName:@"CSVWindow"]) ) {

        NSLog(@"CSVWindowController init failed");
        return nil;
    }

    window = [self window];
    NSLog(@"CSVWindowController init");

    [window orderOut:nil]; // to hide it
    NSLog(@"CSVWindowController hiding the window");

    return self;
}
  

Но окно есть, отображается.

Пожалуйста, не у меня VisibleAtLaunch не помечен, эта консоль правильно отображает мои сообщения, и даже если я изменю:

         [window orderOut:nil]; // to hide it
to 
        [window orderOut:self]; // to hide it
  

Результат тот же, отображается окно.

Любая помощь приветствуется, спасибо 🙂

Ответ №1:

Хорошо, я снова отвечаю на свой собственный вопрос, но на этот раз положительным замечанием. Я думаю, то, что я делал неправильно, было как-то связано со скрытыми — для меня — последствиями архитектуры на основе документов шаблона приложения Document по умолчанию.

Я пробовал использовать другой подход, создавая приложение с нуля, НЕ помечая «Приложение на основе документов» и предоставляя ему:

  • 1 Подкласс NSDocument
  • 2 подкласса NSWindowControllers
  • 1 MainMenu.xib
  • 2 window.xib

и я принудительно создал экземпляр подклассов NSWindowController в коде MyDocument.

Я также поместил IBActions для элементов меню в MyDocument и привязал объект MyDocument к элементам меню в MainMenu.xib.

На этот раз я смог сделать все, что угодно, скрывая / показывая окна, начинающиеся с одного скрытого, не включая пункты меню автоматически по желанию.

Далее следует код для любого новичка вроде меня, которому, возможно, придется бороться с этим в будущем.

 //  MyDocument.h
#import <Cocoa/Cocoa.h>
#import "testWindowController.h"
#import "test2WindowController.h"

@interface MyDocument : NSDocument {
    testWindowController *test;
    test2WindowController *test2;

}

- (IBAction)showWindow1:(id)pId;
- (IBAction)showWindow2:(id)pId;
- (IBAction)hideWindow1:(id)pId;
- (IBAction)hideWindow2:(id)pId;

@end


//  MyDocument.m
#import "MyDocument.h"
#import "testWindowController.h"
#import "test2WindowController.h"

@implementation MyDocument

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
        NSLog(@"MyDocument init...");
        [self makeWindowControllers];
    }

    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (void)makeWindowControllers 
{

    test = [[testWindowController alloc] init];
    test2 = [[test2WindowController alloc] init];  

    [self addWindowController:test];
    [self addWindowController:test2];

    // start hiding the first window
    [[test window] orderOut:self];
}

- (IBAction)hideWindow1:(id)pId
{
    NSLog(@"hideWindow1");
    [[test window] orderOut:self];
}

- (IBAction)showWindow1:(id)pId
{
    NSLog(@"showWindow1");
    [test showWindow:self];
    [[test window] makeKeyAndOrderFront:nil]; // to show it
}

- (IBAction)hideWindow2:(id)pId
{
    NSLog(@"hideWindow2");
    [[test2 window] orderOut:self];
}

- (IBAction)showWindow2:(id)pId
{
    NSLog(@"showWindow2");
    [test2 showWindow:self];
    [[test2 window] makeKeyAndOrderFront:nil]; // to show it
}


 -(BOOL)validateMenuItem:(NSMenuItem *)menuItem {

     NSLog(@"in validateMenuItem for item: %@", [menuItem title]);

     if ([[menuItem title] isEqualToString:@"Show Window"] 
         amp;amp; [[test window] isVisible]){
         return NO;
     }

     if ([[menuItem title] isEqualToString:@"Hide Window"] 
         amp;amp; ![[test window] isVisible]){
         return NO;
     }

     if ([[menuItem title] isEqualToString:@"Show Window2"] 
         amp;amp; [[test2 window] isVisible]){
         return NO;
     }

     if ([[menuItem title] isEqualToString:@"Hide Window2"] 
         amp;amp; ![[test2 window] isVisible]){
         return NO;
     }
     return [super validateMenuItem:menuItem];
 }
  

Ответ №2:

Это еще один метод предотвращения раннего отображения окон NSDocument:

  • Окно подкласса NSDocuments в IB
  • Используйте флаг, чтобы сигнализировать, когда содержимое окна готово
  • Переопределить метод makeKeyAndOrderFront.
 @interface DocWindow : NSWindow

@property BOOL inited;

@end

@implementation DocWindow

- (void)makeKeyAndOrderFront:(id)sender
{
    if ( _inited )
        [super makeKeyAndOrderFront:sender];
}

@end

@implementation Document

- (void)windowControllerDidLoadNib:(NSWindowController *)windowController
{
    // prepare window content here.
    ...

    // show doc's window when ready
    DocWindow *win = (DocWindow *)self.window;
    win.inited = YES;
    [win makeKeyAndOrderFront:self];
}

@end