NSViewController和来自Nib的多个子视图 [英] NSViewController and multiple subviews from a Nib

查看:120
本文介绍了NSViewController和来自Nib的多个子视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Interface Builder和NSViewController载入视图时遇到了困难。



我的目标是创建一个符合以下描述的视图:顶部顶部栏(如工具栏,但不完全一样),它跨越视图的整个宽度,下面是第二个内容视图。这个复合视图由我的 NSViewController 子类拥有。



使用Interface Builder是有意义的。我创建了一个视图nib,并添加到它两个子视图,正确地布局(与顶部栏和内容视图)。我已将文件的所有者设置为 MyViewController 和连接的插座等。



我希望加载的视图(栏和内容)也在自己的nibs中(这可能是引发我的),那些nibs的自定义类设置为相应的NSView子类适用。我不确定要设置为他们的文件的所有者(我猜猜 MyController ,因为它应该是他们的所有者)。



唉,当我初始化一个 MyViewController 的实例时,我已经将它添加到我的Window的contentView正确(我已经检查过),实际上,事情的负载。也就是说, awakeFromNib 被发送到条形视图,但它不会显示在窗口中。我想我肯定有一些电线穿过某处。



EDIT 一些代码可以显示我在做什么



控制器在应用程序完成启动时从应用程序委托加载:

  MyController * controller = [[MyController alloc] initWithNibName:@MyControllerbundle:nil]; 
[window setContentView:[controller view]];

然后在我的initWithNibName中,我现在不做任何事情, $

当解析每个视图到自己的nib并使用 NSViewController ,处理事情的典型方式是为每个nib创建一个 NSViewController 子类。然后,每个相应nib文件的文件所有者将被设置为 NSViewController 子类,并且将连接视图出口到您的自定义视图中的笔尖。然后,在控制主窗口内容视图的视图控制器中,实例化每个 NSViewController 子类的实例,然后将该控制器的视图添加到您的窗口。



一个快速的代码 - 在这段代码中,我调用主内容视图控制器 MainViewController ,控制器的工具栏 TopViewController ,其余内容为 ContentViewController

  // MainViewController.h 
@interface MainViewController:NSViewController
{
//这些只是包含在主要nib文件中的自定义视图服务
//作为占位符,用于插入来自其他nibs的视图
IBOutlet NSView * topView;
IBOutlet NSView * contentView;
TopViewController * topViewController;
ContentViewController * contentViewController;
}

@end

//MainViewController.m
@implementation MainViewController

// loadView在NSViewController中声明,但awakeFromNib也会工作
//这是首选在initWithNibName中执行的事情:bundle:因为
//视图被延迟加载,所以你不需要去加载其他nibs
//直到你自己的nib实际上已经加载。
- (void)loadView
{
[super loadView];
topViewController = [[TopViewController alloc] initWithNibName:@TopViewbundle:nil];
[[topViewController view] setFrame:[topView frame]];
[[self view] replaceSubview:topView with:[topViewController view]];
contentViewController = [[ContentViewController alloc] initWithNibName:@ContentViewbundle:nil];
[[contentViewController view] setFrame:[contentView frame]];
[[self view] replaceSubview:contentView with:[contentViewController view]];
}

@end


I'm having a difficult time wrapping my head around loading views with Interface Builder and NSViewController.

My goal is to have a view which meets the following description: Top bar at the top (like a toolbar but not exactly) which spans the entire width of the view, and a second "content view" below. This composite view is owned by my NSViewController subclass.

It made sense to use Interface Builder for this. I have created a view nib, and added to it two subviews, laid them out properly (with the top bar and the content view). I've set File's Owner to be MyViewController, and connected outlets and such.

The views I wish to load in (the bar and the content) are also in their own nibs (this might be what's tripping me up) and those nibs have their Custom Class set to the respective NSView subclass where applicable. I'm not sure what to set as their File's Owner (I'm guessing MyController as it should be their owner).

Alas, when I init an instance of MyViewController none of my nibs actually display. I've added it to my Window's contentView properly (I've checked otherwise), and actually, things sort of load. That is, awakeFromNib gets sent to the bar view, but it does not display in the window. I think I've definitely got some wires crossed somewhere. Perhaps someone could lend a hand to relieve some of my frustration?

EDIT some code to show what I'm doing

The controller is loaded when my application finishes launching, from the app delegate:

MyController *controller = [[MyController alloc] initWithNibName:@"MyController" bundle:nil];
[window setContentView:[controller view]];

And then in my initWithNibName I don't do anything but call to super for now.

解决方案

When breaking out each view into its own nib and using NSViewController, the typical way of handling things is to create an NSViewController subclass for each of your nibs. The File's Owner for each respective nib file would then be set to that NSViewController subclass, and you would hook up the view outlet to your custom view in the nib. Then, in the view controller that controls the main window content view, you instantiate an instance of each NSViewController subclass, then add that controller's view to your window.

A quick bit of code - in this code, I'm calling the main content view controller MainViewController, the controller for the "toolbar" is TopViewController, and the rest of the content is ContentViewController

//MainViewController.h
@interface MainViewController : NSViewController
{
    //These would just be custom views included in the main nib file that serve
    //as placeholders for where to insert the views coming from other nibs
    IBOutlet NSView* topView;
    IBOutlet NSView* contentView;
    TopViewController* topViewController;
    ContentViewController* contentViewController;
}

@end

//MainViewController.m
@implementation MainViewController

//loadView is declared in NSViewController, but awakeFromNib would work also
//this is preferred to doing things in initWithNibName:bundle: because
//views are loaded lazily, so you don't need to go loading the other nibs
//until your own nib has actually been loaded.
- (void)loadView
{
    [super loadView];
    topViewController = [[TopViewController alloc] initWithNibName:@"TopView" bundle:nil];
    [[topViewController view] setFrame:[topView frame]];
    [[self view] replaceSubview:topView with:[topViewController view]];
    contentViewController = [[ContentViewController alloc] initWithNibName:@"ContentView" bundle:nil];
    [[contentViewController view] setFrame:[contentView frame]];
    [[self view] replaceSubview:contentView with:[contentViewController view]];
}

@end

这篇关于NSViewController和来自Nib的多个子视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆