UIView和initWithFrame以及一个NIB文件。如何加载NIB文件?

时间:2011-02-20 09:33:15

标签: ios objective-c

我有一个名为UIView的{​​{1}},其中我有baseView,其中我添加了一些其他视图并执行一些自定义操作。同一视图也有一个NIB文件。

现在我有一个名为initWithFrame的{​​{1}}类,其中我想将UIViewController视图添加到AppController视图的视图中,所以我这样做:< / p>

baseView但问题是NIB文件没有加载。如何确保自定义内容和NIB文件加载/运行?

5 个答案:

答案 0 :(得分:170)

您有很多选择,具体取决于您的“baseView”类如何使用并集成到您的应用程序中。目前还不清楚你打算如何使用这个类 - 作为UIViewController子类中的视图,或者作为可重用的模块化组件意味着在整个应用程序中多次实例化,以便在许多不同的视图控制器中使用。

如果您的视图是UIViewController子类中唯一的视图,那么Phonitive是正确的 - 将它与UIViewController子类.xib文件捆绑在一起,并使用UIViewController的viewDidLoad进行最终初始化。

但是如果你希望你的View类是在不同的视图控制器中重复使用多次的子组件,通过代码或通过包含在另一个控制器的.xib文件中进行集成,那么你需要实现initWithFrame:init方法,和awakeFromNib,以处理这两种情况。如果您的内部初始化总是包含来自.xib的某些对象,那么在您的initWithFrame中,您需要手动加载.xib以支持想要通过代码创建窗口小部件的“客户”类。同样,如果.xib文件包含您的对象,那么您需要确保从awakeFromNib调用任何代码所需的最终化。

以下是如何使用nib中的UI设计创建UIView子类组件的示例。

MyView.h:

@interface MyView : UIView
{
    UIView *view;
    UILabel *l;
}
@property (nonatomic, retain) IBOutlet UIView *view;
@property (nonatomic, retain) IBOutlet UILabel *l;

MyView.m:

#import "MyView.h"
@implementation MyView
@synthesize l, view;

- (id)initWithFrame:(CGRect)frame 
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        // Initialization code.
        //
        [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
        [self addSubview:self.view];
    }
    return self;
}

- (void) awakeFromNib
{
    [super awakeFromNib];

    // commenters report the next line causes infinite recursion, so removing it
    // [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
    [self addSubview:self.view];
}

- (void) dealloc
{
     [l release];
     [view release];
     [super dealloc];
}

这是nib文件的样子(除了文件的所有者需要更改为MyView类)。

enter image description here

务必将视图和标签出口连接到文件所有者。而已!用于创建可重用的UIView小部件的模板。

关于这个结构的真正好处是你可以将MyView对象的实例放在其他nib文件中,只需将UIView放在你想要的位置/大小,然后在身份检查器(CMD-4)中更改类对于MyView和繁荣,你有一个你想要的任何视图的小部件实例!就像UIKit对象一样,您可以实现委托协议,以便使用您的窗口小部件的对象可以被通知有趣的事件,并且可以提供要在窗口小部件中显示的数据以进行自定义。

答案 1 :(得分:3)

我在尝试在我的应用中执行此操作后遇到问题后发现此帖子。我试图在ViewDidLoad方法中从NIB实例化视图,但控件的作用就像它们被禁用一样。我努力尝试直接设置userInteractionEnabled属性并以编程方式为此视图中的按钮设置触摸事件选择器。没有任何效果。我偶然发现了另一篇帖子,发现viewDidLoad可能还不能加载这个NIB。我将负载移动到ViewWillAppear方法,一切正常。希望这有助于其他人努力解决这个问题。主要的反应非常好,现在我可以从适当的位置调用它。

答案 2 :(得分:2)

如果你想使用NIB,你的UIView最好与UIViewController链接,在这种情况下你可以使用

UIViewController *vc=[[UIViewController alloc] initWithNibName:@"YourNIBWihtOUTEXTENSION" bundle:nil]

[self.view addSubView:vc.view ];

因为内存泄漏,你必须释放vc

答案 3 :(得分:0)

如果你有一个带有xib文件的自定义UIView。

- (id)initWithFrame:(CGRect)frame
{
   self = [super initWithFrame:frame];

   id mainView;
   if (self)
   {
       NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"HomeAllAdsView" owner:self options:nil];
       mainView = [subviewArray objectAtIndex:0];    
   }
   return mainView;
}

- (void) awakeFromNib
{
   [super awakeFromNib];
}

答案 4 :(得分:0)

这篇文章帮助了我Building Reusable Views With Interface Builder and Auto Layout。诀窍是将IBOutlets设置为FileOwner,然后在加载nib后将内容视图添加到自身