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

时间:2022-09-06 20:22:27

If I create an individual nib file and load it in my viewcontroller and assign it to an ivar like so:

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

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

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

Is it possible to create IBOutlets to any thing on it in the nib, like activity indicators? Would File's Owner be the viewcontroller, even though IB wouldn't know this, since it is made an object in code?

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

Is loading the nib the way I've done it the acceptable practice?

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

Perhaps the more acceptable practice is to also create a .h/.m, and use that as the class for the XIB, in which case File's Owner is the new custom class; i'd still need to use the above method in my controller, though, when creating the ivar from the custom class, right? Or is there a better way to do all this, without using the controller's xib?

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

UPDATE: Based on some answers, I did the following. I got rid of the NSBundle method above, and instead just do this:

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

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

@property(非原子,保留)IBOutlet UIView * loadingview;

In the nib file for this view, I click on File's Owner and change the Custom Class to my viewcontroller. Then I control-drag from File's Owner to the View and it links up fine.

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

I would assume at this point that I now have an ivar in my controller, self.loadingview that contains the information in the nib. However this isn't the case. I removed the NSBundle method, assuming the controller will now load the nib directly through the IB outlet, but the view in the nib does not show up and I have no control over it in the controller.

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

I had also removed this when I removed the NSBundle method:

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

[self.view addSubview:self.loadingview];

[self.view addSubview:self.loadingview];

I'm not clear how the view actually displays at this point; and if it does, where in the view heirarchy it appears? perhaps it is behind other views. I tried this too:

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

[self.view bringSubviewToFront:self.loadingview];

[self.view bringSubviewToFront:self.loadingview];

But the view just isn't there. In an effort to find it, I did:

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

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

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

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

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

both with and without the commented part. I get this:

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

index: 2147483647

指数:2147483647

3 个解决方案

#1


6  

Just because you have created a nib and inside that nib hooked up the outlet on File's Owner does not automatically load that nib from your view controller.

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

You can use the UINib class for this:

您可以使用UINib类:

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

Once you do instantiateWithOwner:self, the nib will be loaded and self will be used as the File's Owner and the view from within the nib will be connected to your loadingView property.

一旦你做了instantiateWithOwner:self,将加载nib并将self用作文件的所有者,并且nib中的视图将连接到你的loadingView属性。

You still need to call [self.view addSubview:self.loadingView] to add it to the screen.

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

#2


1  

Interface Builder will know of the file's owner that you sent through the owner:self argument. What you need to do to make your IBOutlets show up in Interface Builder is to set the correct class of the File's Owner in IB under the Identity and Type tab.

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

#3


1  

Is it possible to create IBOutlets to any thing on it in the nib, like activity indicators? Would File's Owner be the viewcontroller, even though IB wouldn't know this, since it is made an object in code?

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

They wouldn't be IBOutlets, but yes, you can wire connections by hand. IBOutlet is an empty macro. It exists exclusively so that Interface Builder can find the properties you would like it to wire to. But the IBOutlet keyword has absolutely no impact on the runtime (it's not even seen by the compiler). Similarly IBAction is a macro that is replaced with void. Nothing about Interface Builder exists at runtime.

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

When the nib loader reads the nib file, it deserializes each object and then for each connection, it sends a setter message (setFoo:) to the connection target passing the new object. After it has finished that for every object in the nib file, it sends awakeFromNib to every object it created. Objects with a connection target of nil are sent to the "owner" (which is self in your example). Note that the file owner is not created by the nib loader. The nib loader has no control over the actual class of the file owner. It's up to you to make sure that the file owner responds to the set...: calls or you'll crash.

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

Is loading the nib the way I've done it the acceptable practice?

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

I would not rely on loadingView being the first top-level object. The order of objects is not defined. Instead, you should use IB to wire the view to the loadingView property of File Owner.

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

Perhaps the more acceptable practice is to also create a .h/.m, and use that as the class for the XIB, in which case File's Owner is the new custom class; i'd still need to use the above method in my controller, though, when creating the ivar from the custom class, right? Or is there a better way to do all this, without using the controller's xib?

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

The traditional way to do it is to have a UIViewController for each nib file in iOS. But that's isn't required. On Mac, NSViewController is pretty new and doesn't work as well as UIViewController, so there isn't as strong a tradition there. Hand-loading like I'm describing is more common there, though most things are still handled through NSWindowController.

传统的方法是在iOS中为每个nib文件使用UIViewController。但这不是必需的。在Mac上,NSViewController非常新,并且不像UIViewController那样工作,因此没有那么强大的传统。尽管大多数事情仍然通过NSWindowController处理,但我正在描述的手动加载在那里更常见。

If you want to do these kinds of things, Nib Files in the Resource Programming Guide is required reading.

如果你想做这些事情,资源编程指南中的Nib文件是必读的。

#1


6  

Just because you have created a nib and inside that nib hooked up the outlet on File's Owner does not automatically load that nib from your view controller.

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

You can use the UINib class for this:

您可以使用UINib类:

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

Once you do instantiateWithOwner:self, the nib will be loaded and self will be used as the File's Owner and the view from within the nib will be connected to your loadingView property.

一旦你做了instantiateWithOwner:self,将加载nib并将self用作文件的所有者,并且nib中的视图将连接到你的loadingView属性。

You still need to call [self.view addSubview:self.loadingView] to add it to the screen.

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

#2


1  

Interface Builder will know of the file's owner that you sent through the owner:self argument. What you need to do to make your IBOutlets show up in Interface Builder is to set the correct class of the File's Owner in IB under the Identity and Type tab.

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

#3


1  

Is it possible to create IBOutlets to any thing on it in the nib, like activity indicators? Would File's Owner be the viewcontroller, even though IB wouldn't know this, since it is made an object in code?

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

They wouldn't be IBOutlets, but yes, you can wire connections by hand. IBOutlet is an empty macro. It exists exclusively so that Interface Builder can find the properties you would like it to wire to. But the IBOutlet keyword has absolutely no impact on the runtime (it's not even seen by the compiler). Similarly IBAction is a macro that is replaced with void. Nothing about Interface Builder exists at runtime.

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

When the nib loader reads the nib file, it deserializes each object and then for each connection, it sends a setter message (setFoo:) to the connection target passing the new object. After it has finished that for every object in the nib file, it sends awakeFromNib to every object it created. Objects with a connection target of nil are sent to the "owner" (which is self in your example). Note that the file owner is not created by the nib loader. The nib loader has no control over the actual class of the file owner. It's up to you to make sure that the file owner responds to the set...: calls or you'll crash.

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

Is loading the nib the way I've done it the acceptable practice?

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

I would not rely on loadingView being the first top-level object. The order of objects is not defined. Instead, you should use IB to wire the view to the loadingView property of File Owner.

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

Perhaps the more acceptable practice is to also create a .h/.m, and use that as the class for the XIB, in which case File's Owner is the new custom class; i'd still need to use the above method in my controller, though, when creating the ivar from the custom class, right? Or is there a better way to do all this, without using the controller's xib?

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

The traditional way to do it is to have a UIViewController for each nib file in iOS. But that's isn't required. On Mac, NSViewController is pretty new and doesn't work as well as UIViewController, so there isn't as strong a tradition there. Hand-loading like I'm describing is more common there, though most things are still handled through NSWindowController.

传统的方法是在iOS中为每个nib文件使用UIViewController。但这不是必需的。在Mac上,NSViewController非常新,并且不像UIViewController那样工作,因此没有那么强大的传统。尽管大多数事情仍然通过NSWindowController处理,但我正在描述的手动加载在那里更常见。

If you want to do these kinds of things, Nib Files in the Resource Programming Guide is required reading.

如果你想做这些事情,资源编程指南中的Nib文件是必读的。