如何获得视图内容的NSViewController取决于它的初始化方式?

时间:2010-07-17 18:39:54

标签: objective-c cocoa nsviewcontroller

这实际上是一个两部分问题,希望我的解释清楚:

我有一个NSViewController,可以配置为在其视图的一部分上显示不同的自定义视图。例如,它的视图可以显示CustomViewA或CustomViewB。

我能够通过为每个自定义视图创建一个NSViewController并使用处理CustomViewA的NSViewController或处理CustomViewB的NSViewController初始化MyViewController来完成这项工作。我使用NSBox并将其contentView设置为给定NSViewController提供的视图。

这种方法的问题在于我有一个NSBox,其contentView将持有“MyView”,然后在“MyView”内部我有另一个NSBox,它将容纳CustomViewA或CustomViewB。

另一个问题是我希望MyViewController同时处理CustomViewA和CustomViewB,而不是每个都有一个单独的NSViewController。

以下是我当前解决方案的示例代码:

// How I initialize the NSViewControllers
CustomViewControllerA* cvc = [[CustomViewControllerA alloc] initWithNibName:@"CustomViewA" bundle:nil];
MyViewController* controller = [[MyViewController alloc] initWithCustomViewController:cvc nibName:@"MyView" bundle:nil];

//...

// In Controller of main view
- (void)awakeFromNib
{
    // container is an NSBox*
    [self.container setContentView:[self.myViewController view]];
}

//...

//  In MyViewController
-(void)awakeFromNib
{
    // content is an NSBox*
    [self.content setContentView:[self.customViewController view]];
}

如何在MyView.nib中安装我的CustomViewA和CustomViewB,并且它们都使用MyViewController作为控制器?

如何让主视图保持MyView而不是NSBox?

提前致谢!

3 个答案:

答案 0 :(得分:2)

以下是我可能会对此进行设置的方式。

@interface MyViewController : NSViewController
{
    IBOutlet NSView* customView; //initially points to an NSBox or generic custom view from the nib file
    CustomViewControllerA* viewControllerA;
    CustomViewControllerB* viewControllerB;
}

@end

@implementation MyViewController

- (void)switchToCustomViewController:(NSViewController*)newCustomViewController
{
    //Make sure the subview gets put in the right location
    [newCustomViewController.view setFrame:customView.frame];
    [self.view replaceSubview:customView withView:newCustomViewController.view];
    customView = newCustomViewController.view;
}

//I usually use loadView in NSViewControllers rather than awakeFromNib, but either works
- (void)loadView
{
    [super loadView];
    viewControllerA = [[CustomViewControllerA alloc] initWithNibName:@"CustomViewA" bundle:nil];
    viewControllerB = [[CustomViewControllerB alloc] initWithNibName:@"CustomViewB" bundle:nil];
    [self switchToCustomViewController:viewControllerA];
}

@end

因此,不是将自定义视图放在NSBox中,这个设置会将一个包含在nib中的视图作为临时占位符,只有在第一次切换到其中一个自定义视图时才会被删除。然后,当您想要交换时,只需使用要切换到的控制器调用-switchToCustomViewController:即可。从那时起,当你切换时,你只是将另一个自定义视图换成另一个自定义视图作为MyViewController视图的直接子视图。如果您希望能够指定哪一个应该是最初使用的那个,只需创建一个init方法或简单属性,可以设置为告诉MyViewController哪个自定义视图应该是首先使用的视图。

答案 1 :(得分:0)

试试这个:

// In MyViewController.m
- (void) awakeFromNib {
  [self.view addSubview:[self.customViewController.view]];
}

并且你的MyViewController必须有一个参数,如:

// In MyViewController.h
@interface MyViewController : NSViewController {
  IBOutlet NSViewController* customViewController;
}

答案 2 :(得分:0)

NSViewController实际上并不打算处理多个交换进出的视图。它主要用于处理从Nib / Xib加载的单个视图,管理顶级对象的内存并提供方便的绑定功能。典型的使用模型是为每个视图创建子类NSViewController,正如您目前所做的那样。