如何在我现有的自定义UIView中引入NIB文件的使用?

时间:2011-07-13 07:16:38

标签: iphone ios uiview

如何在现有的自定义UIView中引入NIB文件的使用?例如:

a)如果将名称命名为* .h&,NIB应该以某种方式自动加载* .m文件? (即我在这里谈的是自定义UIView,而不是UIControllerView)

b)如果你必须手动完成,你需要使用“[[NSBundle mainBundle] loadNibNamed:@”NIBfilename“owner:self options:nil];”也许?

c)如果是(上面的b),那么在自定义视图的“ - (id)initWithCoder:(NSCoder *)编码器”方法中是否使用方法?

PS。用于讨论@ Katfish的答案。 Katfish,当我把“NSArray * nibs = [[NSBundle mainBundle] ...”这一行放入“initWithCoder”的命中递归循环时? [PS看到我刚刚对@ sergio的回答发表评论,这可能解释了这一点?]

// Code within my custom UIView
- (id)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:@"ClockView" owner:self options:nil];
        self = [nibs objectAtIndex:0];
        .
        .
        .
    }
    return self;
}

PSS。注意到我在这里的状态(见Sergio的回答中的评论)我现在想知道我所做的是否可行?基于看到Custom UIView from Interface Builder。也许我可以创建一个自定义UIView,但只能通过从我调用它的UIControllerView以编程方式创建/实例化它?

4 个答案:

答案 0 :(得分:2)

  

a)如果将名称命名为* .h&,NIB应该以某种方式自动加载* .m文件? (即我在这里谈的是自定义UIView,而不是UIControllerView)

据我所知,除了MainWindow之外,没有自动加载nib,UWit根据它在info.plist中指定的内容加载;

  

b)如果你必须手动完成,你需要使用“[[NSBundle mainBundle] loadNibNamed:@”NIBfilename“owner:self options:nil];”也许?

如果您不想实例化视图控制器并且只需要在您的笔尖中定义的顶级对象的数组,那么

loadNibNamed是一个不错的选择。

  

c)如果是(上面的b),那么在自定义视图的“ - (id)initWithCoder:(NSCoder *)编码器”方法中是否使用方法?

如果您从笔尖加载基本视图,我会使用initWithCoder initWithFrame如果您以编程方式创建它。

编辑:

关于你的PS,我猜你将xib文件中的一个对象设置为你定义UIView的{​​{1}}子类的一个实例。 (例如,如果您的initWithCoder子类是UIView,那么您还在xib中实例化了一个视图对象,并将其类设置为MyView。)

如果是这种情况,您需要做的是将文件所有者定义为具体派生的MyView类(例如,UIView);实际上,您已经在实例化MyView派生类,并且在加载nib时,您只需要指定文件的所有者(通过UIView参数)。

编辑2:

实际上我看到实际上我有(a)在父UIControllerView中使用我的自定义视图,在IB中为它的XIB我使用UIView我将类名设置为“clockview”,但是然后(b) )在我的实际clockview自定义UIView(不是UIControllerView)XIB文件我做了同样的事情,并将类名设置为“clockview”。你知道我应该使用什么类名(a)父UIControllerView和(b)自定义UIView本身? (有点困惑) - Greg 1小时前

阅读完评论后,您有两种方法:

第一个选项

    在你的owner相关xib中
  1. ,你做对了;

  2. 在您的其他xib文件中,删除自定义UIViewController(您指定类名UIView的那个;此对象将由第1点的xib创建,因此您不要不需要再次实例化它;选择此“其他xib”的文件所有者,并将其类名设置为clockview

  3. 在这种情况下,您可以像之前一样定义clockwork。这样做的缺点是你在一个笔尖中实例化对象而在另一个笔尖中实例化视图;您将无法在第二个笔尖中定义clockview视图。所以,...

    第二个选项

      在您的initWithCoder相关xib中
    1. ,更改UIViewController班级名称并将其设置为UIView;因此,此视图将是一个“普通”视图,您将用作从第二个xib文件托管另一个视图的空视图;

    2. 在你的其他xib文件中,保留原样;在这种情况下,您可以将文件所有者设置为第1点的UIView

    3. 我认为第二种情况是你的目标。在这种情况下,您不需要在clockview UIViewController中执行任何特定操作;您需要的是,在 initWithCoder 中,在适当的时候加载xib视图;通常这可能在UIViewController(或其他地方,可能在您点击按钮后,取决于您的应用):

      viewDidLoad

      我在这个 - (void)viewDidLoad { [super viewDidLoad]; NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:@"ClockView" owner:self options:nil]; for (NSObject *obj in nibs) { if ( [obj isKindOfClass:[clockview class]]) { [self addSubview:(clockview*)obj]; break; } } } 中正在做的是识别通过加载第二个xib文件来实例化的发条视图;并将其作为子视图添加到控制器的视图中。

      再次,观察我传递给viewDidLoad的{​​{1}}参数;这必须对应于您指定为文件的第二个xib所有者的对象。

      我认为它应该以这种方式运作。

答案 1 :(得分:0)

通常,编写一个继承自NSObject的类yourController,并将nib的文件所有者设置为yourController类。并在yourController类中处理nib加载([[NSBundle mainBundle] loadNibNamed:@“NIBfilename”owner:self options:nil])。
如果你想将一些数据初始化到从nib加载的视图,请使用initWithCoder方法。

答案 2 :(得分:0)

您可以在- (id)init

中为一个UIView指定一个笔尖
- (id)init {

    NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:@"NIBfilename" owner:self options:nil];
    self = [nibs objectAtIndex:0];
    [self retain];

    return self;

}

答案 3 :(得分:0)

a)如果你有一个NIB文件,并且所有者是.h文件,那么当头文件,一个UIViewContoller子类加载了[alloc] initWithNibName时,就会自动加载NIB。

b)是

c)您可以使用initWithNibName方法。

是否要将.xib文件中的组件添加到视图控制器已加载的现有UIView中?

然后你可以用这种方式加载.xib组件,然后从数组中获取组件。

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {


    // open xib and find tableView
    if ( (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) ) {
        NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:nibNameOrNil owner:self options:nil];

        for (NSObject *obj in nibs) {
            if ( [obj isKindOfClass:[UITableView class]]) {
                self.tableContent = (UITableView *) obj;
            }
        }
        self.view = self.tableContent;              

        [self initializeDefaultValues];     
    }

    return self;
}