2012-05-23 4 views
4

Я сломал это в очень маленький проект. Используя следующий код в делегат приложения:Какао: сообщение об ошибке после NSApp beginSheet приводит к скрытию главного окна

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    TestingWindowController * testingWindowController = [[TestingWindowController alloc] initWithWindowNibName: @"TestingWindowController"]; 

    // Begin our sheet 
    [NSApp beginSheet: testingWindowController.window 
     modalForWindow: self.window 
     modalDelegate: self 
     didEndSelector: @selector(windowDidEnd:returnCode:contextInfo:) 
      contextInfo: NULL]; 
} 

- (void)windowDidEnd:(id)alert returnCode:(NSInteger)returnCode contextInfo:(id) contextInfo 
{ 
    // If the user did not accept, then we really don't care what else they did! 
    if (returnCode != NSOKButton) return; 

    // We have had an error. Display it. 
    [[NSApplication sharedApplication] presentError: nil 
            modalForWindow: self.window 
              delegate: nil 
           didPresentSelector: nil 
             contextInfo: NULL]; 
} 

и выполняет следующие действия, привязанных к кнопке на бобах окна. (Обратите внимание, что окно nib также установлено, чтобы оно не было видимым при запуске).

- (IBAction) onClose: (id) sender 
{ 
    [[NSApplication sharedApplication] endSheet: self.window 
            returnCode: NSOKButton]; 

    [self.window orderOut: nil];  
} // End of onClose 

Что в конечном итоге происходит это, когда я в onClose работает, все окна исчезают, и я остался ни с чем, но диалоговое окно ошибки (главное окно исчезло). Error dialog with no main window

Что-то не в порядке с моим кодом? Почему мое главное окно уходит?

ПРИМЕЧАНИЕ. Я знаю, что я не передаю ошибку в метод presentError. Я намеренно оставил этот нуль, поскольку у меня было только короткое время, чтобы написать образец кода. Передача фактической ошибки приводит к такому же поведению.

Образец проекта доступен here.

ответ

1

Вы используете 2 метода, чтобы открыть окно, beginSheet: ..... и runModalForWindow :. Тебе нужен только один из них. Если вам нужен лист, прикрепленный к вашему окну, используйте первый метод, если вы хотите отдельное окно, используйте второе. Аналогично, в методе onClose вы должны использовать endSheet: returnCode: если вы закрываете лист (аргумент для этого метода должен быть проверенWindowController.window not self.window) и stopModalWithCode: если вы закрываете модальное окно, вы не должны иметь обоих.

+0

Спасибо , но, к сожалению, это не решило проблему. Я попытался использовать методы 'beginSheet' и' EndSheet', но я все равно столкнулся с тем же. (Главное окно исчезает). – Kyle

+0

@ Zenox: ваш отредактированный код по-прежнему показывает, что вы закрываете неправильное окно в методе onClose - testingWindowController.window - это лист, который вы хотите завершить, и закажите его не self.window – rdelmar

+0

Метод onClose находится в TestingWindowController (его селектор для нажатия кнопки на панели). Так что self.window был бы правильным в этом контексте, не так ли? – Kyle

4

Похоже, вы все еще используете старую апи, попробуйте новый один

(снимите флажок Всегда виден при запуске в окне UserLoginWindowController)

- (IBAction)userButtonPressed:(id)sender { 

    UserLoginWindowController * wc = [UserLoginWindowController new]; 
    // we keep a reference, so the WC doesn't deallocate 
    self.modalWindowController = wc; 

    [[self window] beginSheet:[wc window] completionHandler:^(NSModalResponse returnCode) { 
     self.modalWindowController = nil; 
    }]; 

} 

в UserLoginWindowController

- (IBAction)cancelButtonPressed:(id)sender { 

    [[[self window] sheetParent] endSheet:[self window] returnCode:NSModalResponseCancel]; 

} 
+0

Да. Новый API, основанный на блоках, сэкономит вам много головной боли. В 10.10 вы также можете использовать раскадровки, чтобы сделать его мертвым простым. (Если вы хотите в нее вскочить) – uchuugaka