即使从NIB加载self,也调用UIView initWithFrame?

时间:2016-07-11 09:41:42

标签: ios objective-c uiview designated-initializer

我继承了一个代码库,发现编译器抱怨这段代码:

- (id)initWithFrame:(CGRect)frame {
// is this really missing??
// self = [super initWithFrame:frame];
    self = [[[NSBundle mainBundle] loadNibNamed:@"DigitsKeyboardView" owner:self options:nil] firstObject];
    return self;
}

XCode抱怨没有调用超类中的指定初始值设定项。如果我取消对super的调用,则错误显然会消失。但是由于应用程序并没有因为某些iOS版本缺少这条线而烦恼,我不确定这是否是学术要求,或者在这种情况下甚至可能是错误的。

使用loadNibNamed调用self方法,然后覆盖self。这会导致麻烦不能立即显现吗?

在这种情况下,适当的实施是什么?

1 个答案:

答案 0 :(得分:2)

  

initWithFrame - 初始化并返回具有指定框架矩形的新分配的视图对象。   视图的框架矩形,以点为单位。框架的原点相对于您计划添加它的superview。此方法使用框架矩形相应地设置中心和边界属性。

     

参数是框架 -   视图的框架矩形,以点为单位。框架的原点相对于您计划添加它的 superview 。此方法使用框架矩形相应地设置中心和边界属性。

所以你应该像这样打电话给

- (id)initWithFrame:(CGRect)frame 
{
  self = [super initWithFrame:frame];
  if (self) 
  {
    // Initialization code
    NSArray *arrNibView = [[NSBundle mainBundle] loadNibNamed:@"DigitsKeyboardView" owner:self options:nil];
    UIView  *nibView = (UIView*)[arrNibView objectAtIndex:0]; //Give here your first object
    [self addSubview:nibView];
  }
  return self;
}

如果您有多个自定义视图,并且如果要将自定义视图用于单独的控制器,则可以使用上述方法。

  

但是如果您有自定义视图并且如果要使用(重用)多个   在多个视图控制器中,你需要实现机器人   initWithFrame和awakeFromNib方法

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

initWithFrame - 建议您实现此方法。您   除了或之外,还可以实现自定义初始化方法   而不是这种方法。

     

awakeFromNib - 在视图及其后调用awakeFromNib   子视图已分配并初始化。它保证了   view将设置其所有插座实例变量。

awakeFromNib的详细说明

  

在实例化过程中,存档中的每个对象都是   取消归档,然后使用适合其类型的方法进行初始化。   Cocoa视图(以及可以使用。自定义的自定义视图)   相关的Interface Builder调色板)使用它们进行初始化   initWithCoder:方法。自定义视图使用它们初始化   initWithFrame:方法。已经实例化的自定义类   使用init方法初始化nib。

     

从归档中实例化并初始化所有对象后,nib加载代码会尝试重新建立连接   在每个对象的出口和相应的目标对象之间。如果   您的自定义对象具有出口,NSNib对象尝试   重新建立您在Interface Builder中创建的任何连接。它   首先尝试使用对象自己建立连接   方法首先。对于需要连接的每个插座,NSNib   object在您的对象中查找setOutletName:形式的方法。   如果该方法存在,NSNib对象将调用它,并传递目标   对象作为参数。如果你没有用它定义一个setter方法   确切的名称,NSNib对象在对象中搜索实例   变量(类型为IBOutlet id),带有相应的插座名称和   尝试直接设置其值。如果一个实例变量带有   无法找到正确的名称,该连接的初始化确实如此   不会发生。最后,在完全初始化所有对象之后,每个对象   收到一条awakeFromNib消息。

Apple文档

UIView

initWithFrame

awakeFromNib

其他来源

Getting Nib File loaded

Initialize a view with xib

awakeFromNib Calling

viewDidLoad and awakeFromNib timing