Переключение между двумя NSWindows

Я делаю простое приложение для Mac, в котором хочу переключать окна.
У меня есть два класса NSWindowController MainWindow и DetailWindow

Я использую этот код:

Класс MainWindow:

//MainWindow.h
@class DetailWindow;
@interface MainWindow : NSWindowController{

    IBOutlet NSButton *btn1;
    DetailWindow *detailwindow;
}
@property (nonatomic, retain) IBOutlet NSButton *btn1;
- (IBAction)btn1Event:(id)sender;

//MainWindow.m

@implementation MainWindow
@synthesize btn1;

- (IBAction)btn1Event:(id)sender {

if (!detailwindow) {
    detailwindow = [[DetailWindow alloc] initWithWindowNibName:@"DetailWindow"];

}
    [detailwindow showWindow:self];
}
@end

Класс DetailWindow:

//DetailWindow.h
@class MainWindow;
@interface DetailWindow : NSWindowController{

    IBOutlet NSButton *backbtn;
    MainWindow *mainwindow;
}
@property (nonatomic, retain) IBOutlet NSButton *backbtn;
- (IBAction)back:(id)sender;

//DetailWindow.m

@implementation DetailWindow
@synthesize backbtn;

- (IBAction)back:(id)sender {

if (!mainwindow) {
    mainwindow = [[MainWindow alloc] initWithWindowNibName:@"MainWindow"];

}
    [mainwindow showWindow:self];
}
@end

Теперь проблема в том, что когда я нажимаю backbtn on DetaiWindow, открывается новый MainWindow.
Итак, у меня есть два MainWindow на экране.
Я хочу, чтобы только главное окно было впереди, когда я нажимаю кнопку BackBtn.

Любая помощь??

Спасибо..!!


person iUser    schedule 15.09.2011    source источник
comment
где mainWindow объявлен в классе DetailWindow?   -  person    schedule 15.09.2011
comment
После объявления backbtn.. позвольте мне отредактировать вопрос..   -  person iUser    schedule 16.09.2011


Ответы (2)


Ваша основная проблема заключается в том, что каждое окно предполагает, что это его собственная работа по созданию другого. У каждого есть ivar для другого, но к нему нет внешнего доступа — через свойство, через IBOutlet или что-то еще — поэтому он всегда начинается как nil, и вместо повторного использования старого создается новая копия.

Есть множество способов обойти это. Вероятно, самым простым было бы создать оба окна в Interface Builder и связать их там, сделав ивары IBOutlet. Тогда вы знаете, что вам вообще никогда не придется создавать их в коде.

Однако, чисто по инерции, вот альтернатива, которая ближе к тому, что у вас уже есть. Обратите внимание: для простоты я предположил, что mainWindow всегда существует первым. Если нет, вам придется дублировать процесс наоборот.

//MainWindow.h
@class DetailWindow;
@interface MainWindow : NSWindowController
{

    IBOutlet NSButton *btn1;
    DetailWindow *detailwindow;
}
@property (nonatomic, retain) NSButton *btn1;
- (IBAction)btn1Event:(id)sender;

//MainWindow.m

@implementation MainWindow
@synthesize btn1;

- (IBAction)btn1Event:(id)sender
{
    if (!detailwindow)
    {
        detailwindow = [[DetailWindow alloc] initWithWindowNibName:@"DetailWindow"];

        // having created the other window, give it a reference back to this one
        detailWindow.mainWindow = self;
    }

    [detailwindow showWindow:self];
}
@end

//DetailWindow.h
@class MainWindow;
@interface DetailWindow : NSWindowController
{

    IBOutlet NSButton *backbtn;
    MainWindow *mainwindow;
}
@property (nonatomic, retain) NSButton *backbtn;

// allow the main window to be set from outside
@property (nonatomic, retain) MainWindow *mainWindow;
- (IBAction)back:(id)sender;

//DetailWindow.m

@implementation DetailWindow
@synthesize backbtn;
@synthesize mainWindow;

- (IBAction)back:(id)sender
{
    // no window creation on the way back
    NSAssert(mainWindow, "mainWindow not set!");
    [mainwindow showWindow:self];
}
@end

Не проверено, поэтому применяются обычные предостережения.

person walkytalky    schedule 20.09.2011
comment
Большое спасибо за все объяснения по рации ..!! и этот код работает нормально..!! :) - person iUser; 20.09.2011

Вы должны вызвать метод orderFront: с собственным объектом в главном окне.

Для этого необходимо найти ссылку на главное окно. Способ сделать это:

[NSApp mainWindow];

Этот вызов вернет вам указатель на ваше главное окно (если вы сделали что-то не так, вам, возможно, придется просмотреть массив [NSApp windows] для поиска вашего главного окна).

Когда вы нашли окно, отправьте ему сообщение orderFront, выполнив действие (предположим, что приведенный выше код возвращает правильное окно, как объяснялось ранее).

[[NSApp mainWindow] orderFront:self];

и окно должно волшебным образом заказывать фасад.

person albianto    schedule 15.09.2011
comment
Можете ли вы написать код, пожалуйста ?? Я очень новичок в этом .. !! Я попробовал то, что вы сказали, но я думаю, что делаю что-то не так .. поэтому все еще не могу сделать MainWindow спереди .. - person iUser; 16.09.2011
comment
Вы пытались отправить вызов ордера каждому окну в массиве окон? - person albianto; 20.09.2011