尝试从IB中的xib创建自定义视图的无限循环

时间:2013-03-04 15:02:48

标签: ios uiview ios6

这是这个问题的后续问题(custom UIView how-to with IB / Xcode 4.5.1 and iOS Simulator 6.0),但没有必要阅读 - 这是我第一次尝试创建一个自定义的UIView,而且显然有些东西我不会这么做提前获得任何帮助。

我有一个从Interface Builder派生的自定义UIView。我想将设置大小设置为200w x 200h,将backgroundColor设置为Green。当我创建时,我做了以下事情:

  1. 通过文件创建新的自定义UIView - >新 - > Objective-C类称为Tview
  2. 通过文件创建新视图 - >新 - >用户界面 - >查看并称之为tnib
  3. 我在Canvas中删除了视图,并从对象检查器添加了一个新视图,并将类名设置为Tview。此外,在“属性”检查器中,我将大小设置为“自由形式”,将背景颜色设置为“绿色”。在“大小”检查器中,我将宽度设置为200,将高度设置为200。

    在我的Tview.m中,我设置了以下内容(我已根据其他SO问题进行了一些更新,但目前尚不清楚这些是否仍然是当前或准确的):

    @implementation Tview
    
    -(id) initWithCoder:(NSCoder *)aDecoder
    {
      NSLog(@"in initWithCoder");
      if((self = [super initWithCoder:aDecoder])) {
        [self setUpView];
        }
      return self;
    }
    
    -(void)awakeFromNib
    {
      NSLog(@"in awakeFromNib");
      [self setUpView];
    }
    
    -(void)setUpView
    {
        NSLog(@"I am in setUpView");
        NSArray *subviewArray=[[NSBundle mainBundle] loadNibNamed:@"tnib" owner:self options:nil];
        UIView *mainView = [subviewArray objectAtIndex:0];
        [self addSubview:mainView];
    }
    
    @end
    

    在我的ViewController.xib中,我拖出一个UIView并将自定义类名设置为Tview。我#import Tview.h文件并从ViewController.xib拖到Tview.h并创建以下属性:

    @property (strong, nonatomic) IBOutlet Tview *myTview;
    

    我构建并运行并获得无限循环的hte:

    2013-03-04 06:49:05.452 Nibtest2[44524:11303] in initWithCoder
    2013-03-04 06:49:05.455 Nibtest2[44524:11303] I am in setUpView
    2013-03-04 06:49:05.456 Nibtest2[44524:11303] in initWithCoder
    2013-03-04 06:49:05.458 Nibtest2[44524:11303] I am in setUpView
    2013-03-04 06:49:05.459 Nibtest2[44524:11303] in initWithCoder
    2013-03-04 06:49:05.460 Nibtest2[44524:11303] I am in setUpView
    

    直到它最终崩溃。

    我在这里做错了什么?

    事先提前

2 个答案:

答案 0 :(得分:4)

您的代码设置了无限递归:initWithCoder:调用setUpView,它从包中实例化一个新的UIView,从而间接调用initWithCoder:并完成循环。

在读取相同NIB时,不应在访问的代码中访问NIB。您应该在包含对象的代码中读取NIB,而不是在Tview对象本身的代码中读取。否则,你会得到无限循环。

您需要完全远离setUpView,以及来自awakeFromNibinitWithCoder:的来电。通过从对象检查器拖出来在界面构建器中建立的连接似乎已经导致NIB文件正确加载,这可以通过调用initWithCoder:来证明。您可能需要的唯一一条是:

[self addSubview:mainView];

但是,它不应该在Tview的代码中:它需要移动到具有myTview属性的父控制器,并且应该修改为

[self.view addSubview:_myTview];

将此行添加到viewDidLoad。它应该解决这个问题。

答案 1 :(得分:0)

实际上我对这个问题的解决方法是,在我的CustonViewController中的viewDidLoad中加载视图,我想在那里使用这样的视图:

myAccessoryView = NSBundle.mainBundle().loadNibNamed("MyAccessoryView", owner: self, options: nil)[0] as! MyAccessoryView

请勿以loadView()方式加载视图! loadView方法用于加载自定义ViewController的视图。