Possible to close an NSAlert sheet manually?

Hello everyone,

I find myself in a bit of a timing problem. I have a confirmation dialog that asks the user to continue or cancel using an NSAlert, but the operation that is performed if the user clicks yes takes a fair bit of time, so I want to display a custom sheet over my main window, but due to a timing problem the NSAlert sheet stays opened behind the custom one, thus when I ask the custom sheet to go away, the whole main window disappears.

Any way to close the alert and then perform the operation? It seems that even if the custom sheet is not displayed, the OK button on the alert sheet stays in a “clicked” state until the operation is over and then it goes away.

What I’d like is the alert to close, then display the custom sheet, do the operation, then close the custom sheet.

I’ve looked in the NSAlert class, but there is no instance or class methods that either closes the alert sheet or lets me see if it is visible.

Saw this in the docs:

- (void)sheetDidEndShouldClose: (NSWindow *)sheet eturnCode: (NSInteger)returnCode contextInfo: (void *)contextInfo
    if (returnCode == NSAlertAlternateReturn) {
        [sheet close];
        [self showMoreInfo: (NSWindow *)contextInfo];
    if (returnCode == NSAlertDefaultReturn)
    // delete selected rows here

So I tried:

theSheet's |close|()

And I got an error :

-[NSAlert close]: unrecognized selector sent to instance 0x2054cb100

Any clues?


Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

Alerts aren’t windows, so close won’t work. I suspect the solution is to make your own window/sheet instead of using an alert.

Take a look at the method, beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo: in the NSAlert docs (if an alert over your main window is ok). There is mention in there about using orderOut in your didEndSelector. It seems that would do what you want.


What happens if you use performSelector:withObject:afterDelay: to delay the time-consuming operation?

Alright, this worked:

theSheet's |window|()'s orderOut_(me)

within the alertDidEndSelector that was specified when the user clicks a button.

I thought of doing a performSelector:withObject:afterDelay: but I think that the NSAlert is not ordered out automatically unless every action inside the selector specified when it closes are over, based on this phrase in the docs:

Thanks everyone! This ASOC thing is even more amazing every time I play with it! The things we can do now… :slight_smile:

Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)


Found out that after solving my NSAlert problem, the custom window I was showing using beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo: method caused a strange bug where I could not attach any more sheets to the main window. Found out that after using this method, I also have to do this in order to properly close the sheet loop:

pleaseWaitSheet's orderOut_(me)
tell current application's NSApp to endSheet_(pleaseWaitSheet)

The orderOut: method is not enough it seems.

Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)