我还没有深入研究故事板,但它的工作原理如下:
如果您的应用程序必须支持 10.9 及更低版本,则创建 NSWindowController 子类的自定义
将这样的代码放入 NSDocument 子类中
- (void)makeWindowControllers
{
CustomWindowController *controller = [[CustomWindowController alloc] init];
[self addWindowController:controller];
}
如果您的应用程序有多个窗口,则将它们添加到此处或其他位置(按需加载),但不要忘记将其添加到文档 windowscontroller 数组中(addWindowController:)
如果您创建它们但不想显示所有窗口,则覆盖
- (void)showWindows
{
[controller showWindow:nil]
}
您可以随时在窗口控制器中访问您的模型
- (CustomDocument *)document
{
return [self document];
}
在窗口控制器中使用绑定(窗口控制器子类+键路径中的文档,这是窗口控制器的属性)
[self.textView bind:@"editable"
toObject:self withKeyPath:@"document.readOnly"
options:@{NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName}];
与 iOS 相比,大多数视图都在屏幕上,因此您必须依赖模式:委派、通知、事件(响应程序链),当然还有 MVC。
10.10 优胜美地变更:
NSViewController 从10.10自动添加到响应者链(通常操作的目标未知 | NSApp sendAction:to:from:)
iOS 中熟悉的 viewDidLoad... 等所有委托终于实现了。这意味着我不再看到子类化 NSWindowCotroller 的巨大好处。
NSDocument 子类是必需的,NSViewController 就足够了。
您可以随时访问视图控制器中的数据
- (CustomDocument *)document
{
return (CustomDocument *)[[NSDocumentController sharedDocumentController] documentForWindow:[[self view] window]];
//doesn't work if you do template approach
//NSWindowController *controller = [[[self view] window] windowController];
//CustomDocument *document = [controller document];
}
如果您确实喜欢这样做(符合 KVC/KVO),您可以按照上面的说明进行绑定。
尖端:
为文档中的模型对象正确实现 UNDO,例如或者可耻地调用 updateChangeCount:
[[self.undoManager prepareWithInvocationTarget:self] deleteRowsAtIndexes:insertedIndexes];
不要将与视图/窗口相关的代码放入文档中
将您的应用程序拆分为多个 NSViewController,例如
- (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:AAPLListWindowControllerShowAddItemViewControllerSegueIdentifier]) {
AAPLListViewController *listViewController = (AAPLListViewController *)self.window.contentViewController;
AAPLAddItemViewController *addItemViewController = segue.destinationController;
addItemViewController.delegate = listViewController;
}
}
以前的代码在 windowcontroller 上调用,并以 viewcontroller 作为委托(同样只有在 10.10 之后才可能)
我总是更喜欢使用多个 XIB,而不是一个巨大的故事板/XIB。使用 NSViewController 的以下子类并始终继承它:
#import <Cocoa/Cocoa.h>
@interface MyViewController : NSViewController
@property(strong) IBOutlet NSView *viewToSubstitute;
@end
#import "MyViewController.h"
@interface MyViewController ()
@end
@implementation MyViewController
- (void)awakeFromNib
{
NSView *view = [self viewToSubstitute];
if (view) {
[self setViewToSubstitute:nil];
[[self view] setFrame:[view frame]];
[[self view] setAutoresizingMask:[view autoresizingMask]];
[[view superview] replaceSubview:view with:[self view]];
}
}
@end
- 使用 XIB 将 MyViewController 的子类添加到项目中。重命名 XIB
- Add NSViewController Object to the XIB and change its subclass name
- Change the loading XIB name to name from step 1
- Link view to substitute to the view you want to replace
Check example project Example Multi XIB project
激励自己shapeart or lister or TextEdit
真正的指南是使用Hopper并看看其他应用程序是如何完成的。
PS:您可以将视图/视图控制器添加到响应者链手动。
PS2:如果您是初学者,请不要过度构建。对您的应用程序的运行感到满意。