#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