6

我习惯于为 iOS 编程,而且我已经非常习惯于UIViewController. 现在,我正在创建一个 OSX 应用程序,并且我有一些关于最佳实践的一般性问题。

在一个UIViewController我通常在-(void)viewDidLoad方法中设置我的视图 - 我实际上并没有为它创建一个自定义UIViewUIViewController除非它真的需要它 - 所以UIViewController将视图添加到它自己的视图,删除它们,动画它们等等 - 首先,是一个好习惯?

对于我的主要问题 - OSX 的最佳实践是什么?我喜欢以编程方式创建接口,并且更喜欢这种方式。如果我说创建一个新的自定义窗口并想要管理它的视图。最好的方法是什么,我在哪里最好地实例化用户界面?

摘要:我如何以编程方式构建自定义视图并在 OSX 中的视图和控制器之间建立最佳实践关系?使用视图控制器在其视图中创建视图是否被认为是一种好习惯?

亲切的问候

4

2 回答 2

8

要在 NSViewController 的代码中构造视图,请覆盖 loadView 并确保设置视图变量。不要调用 super 的实现,因为它会尝试从 NSViewController 的 nibName 和 nibBundle 属性加载一个 nib。

-(void)loadView
{
    self.view = [[NSView alloc] init];
    //Add buttons, fields, tables, whatnot
}

对于 NSWindowController,过程非常相似。您应该在 loadWindow 的实现结束时调用 windowDidLoad。此外,如果窗口为 nil,则窗口控制器不会调用 loadWindow,因此您需要在初始化期间调用它。NSWindowController 似乎假设您将在创建控制器之前在代码中创建窗口,除非从笔尖加载。

- (id)initWithDocument:(FFDocument *)document
                   url:(NSURL *)url
{
    self = [super init];
    if (self)
    {
        [self loadWindow];
    }

    return self;
}    
- (void)loadWindow
{
    self.window = [[NSWindow alloc] init];
    //Content view comes from a view controller
    MyViewController * viewController = [[MyViewController alloc] init];
    [self.window setContentView:viewController.view];
    //Your viewController variable is about to go out of scope at this point. You may want to create a property in the WindowController to store it.
    [self windowDidLoad];
}

一些可选的幻想(10.9 及更早版本)

在 10.10 之前,NSViewControllers 不在 OSX 的第一响应者链中。当响应链中存在项目时,菜单将自动为您启用/禁用菜单项。您可能希望使用 NSViewController 属性创建自己的 NSView 子类,以允许它将控制器添加到响应者链中。

-(void)setViewController:(NSViewController *)newController
{
    if (viewController)
    {
        NSResponder *controllerNextResponder = [viewController nextResponder];
        [super setNextResponder:controllerNextResponder];
        [viewController setNextResponder:nil];
    }

    viewController = newController;

    if (newController)
    {
        NSResponder *ownNextResponder = [self nextResponder];
        [super setNextResponder: viewController];
        [viewController setNextResponder:ownNextResponder];
    }
}

- (void)setNextResponder:(NSResponder *)newNextResponder
{
    if (viewController)
    {
        [viewController setNextResponder:newNextResponder];
        return;
    }

    [super setNextResponder:newNextResponder];
}

最后,我使用自定义 NSViewController 覆盖 setView 以在使用自定义视图时设置 viewController 属性。

-(void)setView:(NSView *)view
{
    [super setView:view];
    SEL setViewController = @selector(setViewController:);
    if ([view respondsToSelector:setViewController])
    {
        [view performSelector:setViewController withObject:self];
    }
}

- (BOOL)acceptsFirstResponder
{
    return YES;
}
于 2013-01-26T21:27:27.850 回答
0

对于我的主要问题 - OSX 的最佳实践是什么?我喜欢以编程方式创建接口,并且更喜欢这种方式。如果我说创建一个新的自定义窗口并想要管理它的视图。最好的方法是什么,我在哪里最好地实例化用户界面?

所有这些都是在 awakeFromNib和中完成的init

以下代码创建了许多窗口并将它们存储在数组中。您可以为每个窗口添加视图。每个视图都可能包含您希望拥有的所有控件。

self.myWindow= [[NSWindow alloc] initWithContentRect:NSMakeRect(100,100,300,300)
                                                   styleMask:NSTitledWindowMask
                                                     backing:NSBackingStoreBuffered
                                                       defer:NO];


[self.myWindowArray addObject:self.myWindow];

for (NSWindow *win in self.myWindowArray) {
    [win makeKeyAndOrderFront:nil];
}
于 2013-01-26T19:18:55.130 回答