Below is my typical WindowController module for presenting a modal dialog (could be settings, asking username/password, etc) loaded from a XIB. It seems a bit too complex for something like this. Any ideas how this can be done better/with less code?
Never mind that it's asking for a password, it could be anything. What frustrates me most is that I repeat the same pattern in each and every of my XIB-based modal window modules. Which of course means I could define a custom window controller class, but before doing that I need to make sure this is really the best way of doing things.
#import "MyPasswordWindowController.h"
static MyPasswordWindowController* windowController;
@interface MyPasswordWindowController ()
@property (weak) IBOutlet NSSecureTextField *passwordField;
@end
@implementation MyPasswordWindowController
{
NSInteger _dialogCode;
}
- (id)init
{
return [super initWithWindowNibName:@"MyPassword"];
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self.window center];
}
- (void)windowWillClose:(NSNotification*)notification
{
[NSApp stopModalWithCode:_dialogCode];
_dialogCode = 0;
}
- (IBAction)okButtonAction:(NSButton *)sender
{
_dialogCode = 1;
[self.window close];
}
- (IBAction)cancelButtonAction:(NSButton *)sender
{
[self.window close];
}
+ (NSString*)run
{
if (!windowController)
windowController = [MyPasswordWindowController new];
[windowController loadWindow];
windowController.passwordField.stringValue = @"";
if ([NSApp runModalForWindow:windowController.window])
return windowController.passwordField.stringValue;
return nil;
}
The application calls [MyPasswordWindowController run], so from the point of view of the user of this module it looks simple, but not so much when you look inside.
Set tags on your buttons to distinguish them. Have them both target the same action method:
Get rid of your
_dialogCode
instance variable and-windowWillClose:
method.-[NSApplication runModalForWindow:]
will already center the window, so you can get rid of your-awakeFromNib
method.Get rid of the invocation of
-[NSWindowController loadWindow]
. That's an override point. You're not supposed to call it. The documentation is clear on that point. It will be called automatically when you request the window controller's-window
.Get rid of the static instance of
MyPasswordWindowController
. Just allocate a new one each time. There's no point in keeping the old one around and it can be troublesome to reuse windows.