Reputation: 1937
I'd like to learn to which class may a NSObject belong (other than NSAlert, NSOpenPanel and NSSavePanel) in order to be responsive to the above call (as in the question title). Here's the scenario of what I need to do. A menu-selected action which has to be modal for self.window requires additional user input in form of a dialog more elaborate than "OK/Cancel" (with the actual work-code omitted from example, for simplicity):
- (IBAction)myActionDialog:(id)sender
{
NSPanel *panel = self.myActionPanel;
[panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
;
if (result == 0){
;
}
}];
}
However, the compiler warns:
'NSPanel may not respond to beginSheetModalForWindow:completionHandler'
which in fact proves to be true, yet I don't know how to get around this problem and code the desired behavior. I've been looking for proper documentation, but found nothing, so far. Any experienced advice is very welcome. Thanks in advance!
UPDATE:
This question respects the:
[[NSApplication sharedApplication] beginSheet: modalForWindow: modalDelegate: didEndSelector:
contextInfo: ]
method, which works with almost any subclass of NSPanel, AFAICT. The only problem is that Apple, while announcing it getting deprecated, hasn't yet properly documented a substitution method which would replace it universally, AFAIK.
Upvotes: 1
Views: 8584
Reputation: 1
The code I see seems confusing. This sample is in Objective C. Here is what worked for me.
[[self window]beginSheet:registerPanel
completionHandler:^(NSModalResponse returncode){
NSLog(@"ReturnCode: ");//will not fire, not linked to an IBAction
}
];
Then in above I had outlets created in which I need not worry about the ReturnCode:
-(IBAction)cancelRegister:(id)sender
{
[registerPanel orderOut:self];
[NSApp endSheet:registerPanel];
NSLog(@"cancelRegister ");
}
//end the register dialog - nothing happing here
-(void)didEndRegister
{
//nothing to do
}
//more button outlets below in project ........
The following is the code that was replaced and was outdated.
/* 11-24-18 replaced for below,
[NSApp beginSheet:registerPanel
modalForWindow:[self window]
modalDelegate:self
didEndSelector:@selector(didEndRegister)
contextInfo:nil];
*/
Upvotes: 0
Reputation: 1937
This is my answer to the question, following individual research on the subject. I find a major issue in carefully implementing custom sheets being a rather sudden and silent transition between deprecation and disfunction of the old modal delegate based code, which must have happened sometime during 10.8. It causes a critical compatibility problem requiring a simple code branching and refraining from over-implementing new API enums, unless really needed for a reason. I understand such a concept can be disagreed with, but here's an imlementation. I'm using the Gestalt() command because it works with all systems between 10.7 and 10.10. Being aware there are newer, better and more sophisticated methods for determining OS runtime, here's the link with more relevant info: https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKit/
I'm posting this for simplicity, having the header declaration and interface builder details omitted. Hope it's clear, though:
SInt32 versionMinor;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
versionMinor = 0;
Gestalt(gestaltSystemVersionMinor, &versionMinor);
NSLog(@"Version Minor: %d\n", (int)versionMinor);
}
The sheet posting method:
- (IBAction)postSheet:(id)sender
{
if(versionMinor > 8){
[self.window beginSheet:self.sheet completionHandler:^(NSInteger result) {
if (result == 1) [self doSomething];
if (result == 0) [self doNothing];
}];
}else [[NSApplication sharedApplication] beginSheet:self.sheet
modalForWindow:self.window
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:nil
];
}
OK button pressed IBAction:
- (IBAction)ok:(id)sender
{
[self.sheet orderOut:self];
if(versionMinor > 8){NSLog(@">OK Button pressed\n");
[self.window endSheet:self.sheet returnCode:1];
}else{ NSLog(@"<OK Button pressed\n");
[NSApp endSheet:self.sheet returnCode: 1];
}
}
Likewise, for the Cancel button pressed IBAction:
- (IBAction)cancel:(id)sender
{
[self.sheet orderOut:self];
if(versionMinor > 8){ NSLog(@">Cancel Button pressed\n");
[self.window endSheet:self.sheet returnCode:0];
}else{ NSLog(@"<Cancel Button pressed\n");
[NSApp endSheet:self.sheet returnCode: 0];
}
}
Finally, the "legacy" didEndSelector (for pre-10.8. runtime)
- (void)sheetDidEnd : (NSPanel*)panel returnCode:(NSInteger)returnCode contextInfo:(void*)contextInfo
{
if (returnCode == 1) [self doSomething ];
if (returnCode == 0) [self doNothing ];
}
This works for 10.7 through 10.10, built with either 10.8 or 10.10 SDKs. In the academic and scientific communities OSX 10.7 and 10.8 are still being used quite a bit. Hope someone can find this helpful. Thanks for the contributions and comments.
Upvotes: 2
Reputation: 90661
Apple have documented the replacement for -[NSApplication beginSheet:...]
. It's new methods on NSWindow
:
-beginSheet:completionHandler:
-beginCriticalSheet:completionHandler:
-endSheet:
-endSheet:returnCode:
In your case, you'd do:
[self.window beginSheet:panel completionHandler:^(NSInteger result) {
if (result == 0){
;
}
}];
Upvotes: 2