在没有UIViewController的情况下加载XIB文件

时间:2013-03-25 10:16:48

标签: objective-c xcode uiview interface-builder xib

我想使用Interface Builder设计一个UIView和一些子视图(UIWebView,UIToolbar,一些UIBarButtonItems,一个进度指示器等等),但我认为传统上不需要使用UIViewController,使用presentViewController:animated等。

所以,我创建了一个自定义类,其.h文件代码如下:

@interface FileInteractionManager : NSObject {

}

@property (nonatomic, retain) IBOutlet UIView *fileView;
@property (nonatomic, retain) IBOutlet UIWebView *fileWebView;

@property (nonatomic, retain) IBOutlet UIBarButtonItem *printButton;
@property (nonatomic, retain) IBOutlet UIBarButtonItem *optionsButton;
@property (nonatomic, retain) IBOutlet UIBarButtonItem *doneButton;

我的.m文件如下:

@implementation FileInteractionManager

@synthesize fileView, fileWebView, doneButton, optionsButton, printButton;

-(id)init {

    NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"FileInteractionView" owner:self options:nil];

    NSLog(@"Load success!");

    return self;
}

最后,我创建一个名为'FileInteractionView.xib'的独立xib文件,将文件的所有者更改为我在上面创建的自定义类,然后连接IBOutlets。

当我在我的类上调用init方法时,我可以在调试器中看到我的所有IBOutlet对象都已正确实例化。

我的问题是:

  1. loadNibNamed:owner:options:方法是加载我的独立.xib文件的正确方法吗?我不喜欢这个方法返回一个我没用的数组的事实(返回的顶级对象匹配我的变量fileView,但我已经通过Interface Builder链接了它们)。

  2. 我的一般方法是否正确解决我的问题?我执行了上述步骤,因为我想要一个简单的UIView对象,我可以将其添加到现有的UIViewController中,而不是呈现和关闭一个全新的UIViewController。

2 个答案:

答案 0 :(得分:6)

我使用了一种不同的方法。我创建了UIView(MyCustomView ie)的子类,然后创建了具有视图UI的xib,并将(主)视图类更改为刚定义的视图类。在xib中,您可以将插座链接到自定义视图本身(而不是文件所有者)。 最后在类定义中我创建了一个这样的函数:

+ (id) newFromNib
{
    NSArray *nibArray = [[UINib nibWithNibName:NSStringFromClass([self class]) bundle:nil] instantiateWithOwner:nil options:nil];
    return nibArray[0];
}

只是几个笔记: 1)这是一个类方法,你可以使用“self”只是为了“NSStringFromClass([self class])”,但是真正的对象是返回的变量 2)这个例子假设xib具有相同的类名(通过NSStringFromClass([self class]),所以我可以复制粘贴它而不改变任何东西;))并且你的视图是在xib中定义的第一个(标准)。如果您在一个xib中存储多个“主”视图,请选择正确的元素。

所以在我需要MyCustomView的地方我做了类似的事情:

MyCustomView* mycv = [MyCustomView newFromNib];

然后设置框架/中心并添加到superview ... 我认为这种方式非常有用,如果你有一个复杂UI元素的“库”,并希望通过xib设计它们,然后在需要时添加。

答案 1 :(得分:1)

il Malvagio Dottor Prosciutto回答很好。这是一个可能的替代方案。

在NS_DESIGNATED_INITIALIZER中加载笔尖并成为子视图的所有者

如果我们接受xib只保留子视图而不是视图本身,那么我们可以在@interface MyCustomView () @property (strong, nonatomic) IBOutlet UIView *subview; @end @implementation MyCustomView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil]; [self addSubview:self.subview]; return self; } @end 中加载子视图并在{{1}}中保留所有权结构。

{{1}}