自定义XIB的“文件所有者”

时间:2011-08-25 13:50:09

标签: objective-c interface-builder

如果我创建一个单独的nib文件并将其加载到我的viewcontroller中并将其分配给ivar,如下所示:

self.loadingview=[[[NSBundle mainBundle] loadNibNamed:@"loading" owner:self options:nil] objectAtIndex:0];

是否有可能在笔尖上的任何东西上创建IBOutlets,比如活动指标?文件的所有者是视图控制器,即使IB不知道这个,因为它是代码中的对象吗?

按照我做的方式加载笔尖是可以接受的做法吗?

也许更可接受的做法是创建.h / .m,并将其用作XIB的类,在这种情况下,File的Owner是新的自定义类;但是,我仍然需要在我的控制器中使用上述方法,从自定义类创建ivar时,对吗?或者有没有更好的方法来完成所有这些,而不使用控制器的xib?

更新:根据一些答案,我做了以下工作。我摆脱了上面的NSBundle方法,而只是这样做:

@property (nonatomic, retain) IBOutlet UIView*loadingview;

在此视图的nib文件中,我单击File的Owner并将Custom Class更改为我的viewcontroller。然后我控制 - 从文件的所有者拖动到视图,它链接正常。

我想在这一点上,我现在在我的控制器中有一个ivar,self.loadingview包含nib中的信息。然而事实并非如此。我删除了NSBundle方法,假设控制器现在直接通过IB插座加载nib,但是nib中的视图没有显示,我在控制器中无法控制它。

当我删除NSBundle方法时,我也删除了它:

[self.view addSubview:self.loadingview];

我不清楚视图实际上是如何显示的;如果确实如此,那么看来heirarchy会出现在哪里?也许它落后于其他观点。我也尝试了这个:

[self.view bringSubviewToFront:self.loadingview];

但是这个观点并不存在。为了找到它,我做了:

//[self.view bringSubviewToFront:self.loadingview];

NSLog(@"index: %i",[[self.view subviews]indexOfObject:self.loadingview]);

有和没有评论部分。我明白了:

index: 2147483647

3 个答案:

答案 0 :(得分:6)

只是因为你已经创建了一个笔尖,并且在该文件所有者的插座内连接了该笔芯,并不会自动从视图控制器加载该笔尖。

您可以使用UINib类:

UINib* nib = [UINib nibWithNibName:@"loading" bundle:[NSBundle mainBundle]];
[nib instantiateWithOwner:self options:nil];

执行instantiateWithOwner:self后,将加载笔尖,self将用作文件所有者,并且笔尖内的视图将连接到您的loadingView属性。< / p>

您仍然需要致电[self.view addSubview:self.loadingView]将其添加到屏幕上。

答案 1 :(得分:1)

Interface Builder将知道您通过owner:self参数发送的文件所有者。要使您的IBOutlet显示在Interface Builder中,您需要做的是在标识和类型选项卡下的IB中设置文件所有者的正确类。

答案 2 :(得分:1)

  

是否有可能在笔尖上的任何东西上创建IBOutlets,比如活动指标?文件的所有者是视图控制器,即使IB不知道这个,因为它是代码中的对象吗?

它们不是IBOutlets,但是,您可以手动连接。 IBOutlet是一个空宏。它专门存在,以便Interface Builder可以找到您希望它连接到的属性。但是IBOutlet关键字对运行时没有任何影响(编译器甚至都没有看到它)。同样,IBAction是一个用void替换的宏。在运行时没有任何关于Interface Builder的信息。

当nib加载程序读取nib文件时,它会反序列化每个对象,然后对于每个连接,它会向传递新对象的连接目标发送一个setter消息(setFoo:)。在为nib文件中的每个对象完成该操作后,它会将awakeFromNib发送到它创建的每个对象。连接目标为nil的对象将发送给“所有者”(在您的示例中为self)。请注意,文件所有者不是由nib加载程序创建的。 nib加载器无法控制文件所有者的实际类。您可以确保文件所有者响应set...:来电,否则您将崩溃。

  

按照我做的方式加载笔尖是可以接受的做法吗?

我不会依赖loadingView作为第一个顶级对象。没有定义对象的顺序。相反,您应该使用IB将视图连接到文件所有者的loadingView属性。

  

也许更可接受的做法是创建.h / .m,并将其用作XIB的类,在这种情况下,File的Owner是新的自定义类;但是,我仍然需要在我的控制器中使用上述方法,从自定义类创建ivar时,对吗?或者有没有更好的方法来完成所有这些,而不使用控制器的xib?

传统的方法是在iOS中为每个nib文件设置UIViewController。但这不是必需的。在Mac上,NSViewController是新的,并不像UIViewController那样有效,因此没有那么强大的传统。尽管大部分内容仍然通过NSWindowController处理,但我正在描述的手动加载更为常见。

如果你想做这些事情,需要阅读资源编程指南中的Nib Files