在Cocoa中呈现来自XIB的模态对话:最佳/最短模式?

moj*_*uba 2 cocoa modal-dialog objective-c xib nswindowcontroller

下面是我的典型WindowController模块,用于显示从XIB加载的模式对话框(可能是设置,询问用户名/密码等).这样的事情似乎有点过于复杂.任何想法如何更好/更少的代码?

别介意它要求输入密码,它可能是任何东西.让我最沮丧的是我在每个基于XIB的模态窗口模块中重复相同的模式.这当然意味着我可以定义一个自定义窗口控制器类,但在此之前我需要确保这是最好的做事方式.

#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;
}
Run Code Online (Sandbox Code Playgroud)

应用程序调用[MyPasswordWindowController运行],所以从这个模块的用户的角度来看,它看起来很简单,但是当你向内看时却没那么多.

Ken*_*ses 6

在按钮上设置标签以区分它们.让他们都采用相同的行动方法:

- (IBAction) buttonAction:(NSButton*)sender
{
    [NSApp stopModalWithCode:[sender tag]];
    [self.window close];
}
Run Code Online (Sandbox Code Playgroud)

摆脱你的_dialogCode实例变量和-windowWillClose:方法.

-[NSApplication runModalForWindow:]已经将窗口居中,这样你就可以摆脱你的-awakeFromNib方法了.

摆脱调用-[NSWindowController loadWindow].这是一个覆盖点.你不应该叫它.关于这一点,文档很清楚.当您请求窗口控制器时,它将自动调用-window.

摆脱静态实例MyPasswordWindowController.每次只分配一个新的.保持旧的一个没有意义,重用Windows可能很麻烦.