如何使用工作表的返回值来决定是否关闭窗口?

时间:2009-06-12 01:01:06

标签: cocoa cocoa-sheet

我想在我的NSWindowController子类中使用windowShouldClose:来弹出一张表,询问用户是否想在保存,取消和不保存按钮关闭之前保存更改。

我遇到的问题是beginSheetModalForWindow:...使用委托而不是返回值。

我可以在windowShouldClose:中返回NO,但是当我将[self close]发送到面板代表中的控制器时,没有任何反应。

有人可以向我解释如何做到这一点,还是指向一些示例代码的方向?

2 个答案:

答案 0 :(得分:2)

基本解决方案是在窗口上放置一个布尔标志,指出窗口是否已警告未保存的更改。在调用[self close]之前,将此标志设置为true。

最后,在windowShouldClose方法中,返回标志的值。

答案 1 :(得分:2)

这是我最终使用的代码。

windowShouldCloseAfterSaveSheet_是我的控制器类中的实例变量。

请记住在IB中设置控制器的窗口。

- (BOOL)windowShouldClose:(id)window {    
  if (windowShouldCloseAfterSaveSheet_) {
    // User has already gone through save sheet and choosen to close the window
    windowShouldCloseAfterSaveSheet_ = NO; // Reset value just in case
    return YES;
  }

  if ([properties_ settingsChanged]) {
    NSAlert *saveAlert = [[NSAlert alloc] init];
    [saveAlert addButtonWithTitle:@"OK"];
    [saveAlert addButtonWithTitle:@"Cancel"];
    [saveAlert addButtonWithTitle:@"Don't Save"];
    [saveAlert setMessageText:@"Save changes to preferences?"];
    [saveAlert setInformativeText:@"If you don't save the changes, they will be lost"];
    [saveAlert beginSheetModalForWindow:window
                                modalDelegate:self
                               didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) 
                                  contextInfo:nil];

    return NO;
  }

  // Settings haven't been changed.
  return YES;
}

// This is the method that gets called when a user selected a choice from the
// do you want to save preferences sheet.
- (void)alertDidEnd:(NSAlert *)alert 
         returnCode:(int)returnCode
        contextInfo:(void *)contextInfo {
  switch (returnCode) {
    case NSAlertFirstButtonReturn:
      // Save button
      if (![properties_ saveToFile]) {
        NSAlert *saveFailedAlert = [NSAlert alertWithMessageText:@"Save Failed"
                                                   defaultButton:@"OK"
                                                 alternateButton:nil
                                                     otherButton:nil
                                       informativeTextWithFormat:@"Failed to save preferences to disk"];
        [saveFailedAlert runModal];
      }
      [[alert window] orderOut:self];
      windowShouldCloseAfterSaveSheet_ = YES;
      [[self window] performClose:self];
      break;
    case NSAlertSecondButtonReturn:
      // Cancel button
      // Do nothing
      break;
    case NSAlertThirdButtonReturn:
      // Don't Save button
      [[alert window] orderOut:self];
      windowShouldCloseAfterSaveSheet_ = YES;
      [[self window] performClose:self];
      break;
    default:
      NSAssert1(NO, @"Unknown button return: %i", returnCode);
      break;
  }
}