My sheet window seems dead. And I don't feel well myself…

Hello,

I surely missed something in the docs, but I copied Apple’s code, changed some variable names, like this:

addClassWindow is defined in IB: it has two buttons “OK” and “Cancel” with their standard keyboard equivalents, and a text field to enter a new name (bound to an application’s property).

I get my window as sheet, but it is a dead window: OK button is not pulsating and the text field is inactive. If I click on a button, the window is dismissed but the returnCode is always 0.

To say it more briefly, nothing is working. This time I would have the equivalent of this “pseudocode”:

Lost in documentation. Help me please!

Found! :slight_smile:

You know where it was? Not in the code, stop searching: my “addClassWindow” had no title bar. As it doesn’t appear, I checked off “title bar”. Big, big mistake.

It’s surely documented somewhere. I must have missed it.

Regards,

Ok, next problem, and this time it’s in code:

First of all, Xcode complains that “answer” is not initialized. But if I put NSInteger answer=0; , as it suggests, the return value is always zero.

If I don’t, return value are. anything. Sometimes 0, then -2115504080, nothing useful. So what, this time? a forgotten selector? a missing handler with a lot of parameters? I just want my window to answer “YES” or “NO”. Is it THAT difficult? :mad:

as mentioned in another thread, sheets are document modal (asynchronous) to prevent other documents from being blocked.
This means the endSheet: selector is called after the user presses a button to handle the pressed button and dismiss the sheet

The function NSRunAlertPanel() shows a separate window and returns the button value synchronously

Thank you, Stefan, but this does not help me much…

Your first example for the alert worked well, but here I am not posting an alert, I use NSApp methods for a (normal) window to appear as sheet. I don’t consider myself as particularly stupid, but here I don’t see what’s wrong (especially if I just copy and paste an Apple Doc example.

In that case, I can’t find what’s wrong, and just typing “beginSheet” on the Web tell me I certainly not the first to be in trouble with this window management.

Thanks!

Once you start a modal event loop for a window you can’t then ignore it: “While the application is in that loop, it does not respond to any other events (including mouse, keyboard, or window-close events) unless they are associated with the window”. In this context “associated” means, roughly, initiated by.

But sheets aren’t generally supposed to be application-modal…

Bernard,

First off, you have two methods that show your custom window, one as a sheet (beginSheet:modalForWindow: modalDelegate: didEndSelector: contextInfo:), and one as a stand alone window (runModalForWindow:). You need to choose one – since you mentioned a sheet in your original post, I’ll assume you want a sheet, and so should use the first method. To figure out which button was clicked (and to get the value of your text field) you should define an IBAction and connect it to your buttons, and then check the title of the sender to find out which one. You could do it like this:

- (IBAction)attemptToAddClass:(id)sender {
    [NSApp beginSheet:self.addClassWindow modalForWindow:self.window modalDelegate:nil didEndSelector:nil contextInfo:nil];
}

-(IBAction)closeSheet:(NSButton *)sender { //IBAction for both buttons
     NSLog(@"%@",sender.title);
    [NSApp endSheet:self.addClassWindow];
    [addClassWindow orderOut: self];
}

Ric

Thank you everyone for your enlightments.

Ric, I found this example in “Using Application-Modal Dialogs”, listing 1, where these two methods are called. But maybe I missed something (as thé Docs are always right).

Ric is right but there are more different types of ways to show panels. This is the way you should use it when you want to work with return codes and sheets. I don’t use self.addClassWindow because I assume you won’t declare something like that as an property.

EDIT: when you want localization in you application you should definitely use the method I described here.

Ric, DJ,

I understand that this way of presenting windows (as sheet or normal windows) adds a lot of flexibility (make a dialog modal for the entire application or for one specific document). This flexibility allows you to throw an alert for a part of your application and then proceed with the normal flow. Then, when an alert is cancelled, you can implement the equivalent of «aha, the user at last decided to save his third opened document, ok, I can handle that now».

This, of course, must be implemented in separate handlers. The key thing is to keep a trace of what has sent an alert, what caused it to be dismissed, and what action to take after that. It’s the cost of the flexibility.

Last thing : localization (DJ’s remark). That’s true if you test the title of the button, like in Ric’s solution. But for some time now, I use the tags of the controls, giving for example a unique tag identifier to “OK” buttons, which cannot be differenciated by their title. And a tag of 9999 is the same for “Cancel”, “Annuler”, “Abbrechen” or “Cancelar”.

Anyway, you gave me some useful --and reusable-- pieces of working code! Thanks again!

Something I forgot to mention is that processing a sheet in three steps gives you full control. The advantage is that method confirmAddClass: can behave like a should method. If you have a window that needs to behave like a form, you can check in confirmAddClass: if everything has filled in correctly and decide if you close the sheet or not. Also I set contextInfo mostly to self but can also be the sender to keep track of ‘who triggered the process’ but it can be any object.