JeremyLaurenson
JeremyLaurenson

Reputation: 979

How to programmatically dismiss an NSAlert run modal for window

Thread 1 runs a modal alert:

- (void)didEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
{
[sheet orderOut:self];
};


-(void)newAlert
{
currentAlert=[NSAlert alertWithMessageText:@"Switch drives!" defaultButton:@"Cancel sync" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Please switch disks: %@",reason,nil];
[currentAlert setDelegate:self];
[currentAlert beginSheetModalForWindow:self.window completionHandler:^(NSInteger returnCode)
            {
                mustStop=TRUE;
            }];

}     

Elsewhere, on another thread I want to dismiss the alert, but this doesn't work:

[NSApp endSheet:[self window]];

It does not work.

Upvotes: 3

Views: 4008

Answers (1)

Ken Thomases
Ken Thomases

Reputation: 90571

You can't do GUI operations on background threads. You have to do them on the main thread. So, you could do:

dispatch_async(dispatch_get_main_queue(), ^{
    [NSApp endSheet:self.window];
});

Technically, though, you should be using the new sheet methods on NSWindow for this. So, you should do:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.window endSheet:currentAlert.window];
});

Of course, that means you need to keep track of the alert beyond the -newAlert method. (I suppose you could use self.window.attachedSheet if you didn't keep track of the alert, although there may be a race condition there where the background thread cancels a different sheet than the alert.)

Also, the method -didEndSheet:returnCode:contextInfo: is not used when an alert is run using -beginSheetModalForWindow:completionHandler:.

Upvotes: 7

Related Questions