This question already has answers here:
UIView and initWithFrame and a NIB file. How can i get the NIB file loaded?
                                
                                    (5个答案)
                                
                        
                                3年前关闭。
            
                    
我继承了一个代码库,发现编译器抱怨这段代码:

- (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。这会导致麻烦立即消失吗?

在这种情况下正确的实现是什么?

最佳答案

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


所以你应该这样打电话给下面

- (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
  子视图已分配并初始化。保证
  视图将设置其所有出口实例变量。


awakeFromNib的详细说明


  在实例化过程中,归档中的每个对象都是
  取消存档,然后使用适合其类型的方法进行初始化。
  可可视图(以及可以使用
  关联的Interface Builder面板)使用其初始化
  initWithCoder:方法。自定义视图使用其初始化
  initWithFrame:方法。已实例化的自定义类
  笔尖使用其init方法初始化。
  
  从归档中实例化并初始化所有对象后,nib加载代码将尝试重新建立连接
  在每个对象的出口和对应的目标对象之间。如果
  您的自定义对象有出口,NSNib对象会尝试
  重新建立您在Interface Builder中创建的所有连接。它
  首先尝试使用对象自己的连接建立连接
  方法第一。对于每个需要连接的插座,NSNib
  对象在您的对象中查找setOutletName:形式的方法。
  如果该方法存在,则NSNIb对象调用它,并传递目标
  对象作为参数。如果您没有使用该方法定义setter方法
  确切的名称,NSNIb对象在对象中搜索实例
  变量(具有IBOutlet ID类型)以及相应的出口名称和
  尝试直接设置其值。如果实例变量带有
  找不到正确的名称,该连接的初始化确实
  不会发生。最后,在所有对象完全初始化之后,每个对象
  收到awakeFromNib消息。


苹果文件

UIView

initWithFrame

awakeFromNib

其他来源

Getting Nib File loaded

Initialize a view with xib

awakeFromNib Calling

viewDidLoad and awakeFromNib timing

关于ios - 即使从NIB加载self,也要调用UIView initWithFrame吗? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38303752/

10-12 22:45