下面是我的典型 WindowController 模块,用于呈现从 XIB 加载的模式对话框(可以是设置、询问用户名/密码等)。对于这样的事情来说似乎有点太复杂了。有什么想法可以更好地/用更少的代码来做到这一点吗?
别介意它是否要求输入密码,它可以是任何东西。最让我沮丧的是,我在每个基于 XIB 的模态窗口模块中重复相同的模式。这当然意味着我可以定义一个自定义窗口 Controller 类,但在这之前我需要确保这确实是最好的做事方式。
#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;
}
应用程序调用[MyPasswordWindowController run],因此从该模块的用户的角度来看,它看起来很简单,但当你往里面看时就不那么简单了。
最佳答案
在按钮上设置标签以区分它们。让它们都针对相同的操作方法:
- (IBAction) buttonAction:(NSButton*)sender
{
[NSApp stopModalWithCode:[sender tag]];
[self.window close];
}
删除 _dialogCode
实例变量和 -windowWillClose:
方法。
-[NSApplication runModalForWindow:]
已经使窗口居中,因此您可以摆脱 -awakeFromNib
方法。
摆脱对-[NSWindowController loadWindow]的调用
。这是一个覆盖点。你不应该调用它。 The documentation在这一点上是明确的。当您请求窗口 Controller 的-window
时,它将自动调用。
删除MyPasswordWindowController
的静态实例。每次只需分配一个新的。保留旧窗口是没有意义的,并且重复使用窗口可能会很麻烦。
关于objective-c - 在 Cocoa 中呈现 XIB 的模式对话框 : best/shortest pattern?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20477717/