通过Interface Builder创建的UIView在viewDidLoad中没有子视图

时间:2014-11-26 11:36:49

标签: ios objective-c iphone uibutton interface-builder

上下文:

  • MainView.xib:我已经布置了我的UI元素,并使用autolayout精心对齐它们。有一大堆UIButtons,一个UILabel和一个UIToolbar。层次结构非常平坦:

    UIView // Hooked up to ViewController
    |
    - UILabel
    - UIButton
    - UIButton
    - UIButton
    - ... // more buttons
    - UIToolbar
    
  • ViewController.m

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property NSArray *_allButtons;
    
    // Interface elements
    @property IBOutlet UILabel *titleLabel;
    @property IBOutlet UIButton *button1;
    @property IBOutlet UIButton *button2;
    // ... lots more buttons
    @property IBOutlet UIToolbar *toolbar;
    
    @end
    
    @implementation ViewController
    
    - (void)loadView {
        UIView *mainView = [[[NSBundle mainBundle] loadNibNamed:@"MainView"
                                                          owner:self
                                                        options:nil] objectAtIndex:0];
        self.view = mainView;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // BREAK_POINT
    
        // ... code to wire up the UIButtons to dynamically created objects
    }
    

Wierd观察:

我已经正确地将我单独创建的IBOutlet UIButton button<n>指针连接到.xib文件中的UIButtons。并且该代码工作正常。

然而,像这样单独维护所有按钮是一件痛苦的事。我可以通过编程方式创建它们,但是在Interface Builder中可视化地移动它们(现在我已经学会了如何使用它)。

我想我可以删除UIButtons的IBOutlet连接,并在MainView.xib中找到它们作为主UIView的子视图,在viewDidLoad中有一些这样的代码:

for (UIView *view in self.view.subviews) {
    if( [view isKindOfClass:[UIButton class]]) {
        [self._allButtons addObject:view];
    }
}

不幸的是,self._allButtons变成了一个空阵列。

所以,我带回了IBOutlet连接,放在viewDidLoad的断点处,看到了这个:

(lldb) po self.view
<UIView: 0x7fa7897e2140; frame = (0 0; 600 600); autoresize = W+H; layer = <CALayer: 0x7fa7897e2210>>

(lldb) po self.view.subviews
<__NSArrayI 0x7fa789713500>(

)
(lldb) po [self.view.subviews count];
 nil
(lldb) po self.button1
<UIButton: 0x7fa78955ea70; frame = (-23 -15; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7fa7897663d0>>

这非常奇怪...... button1已初始化,但不是UIView的子视图。

问题:

1。为什么self.view.subviewsviewDidLoad为空?

2。有没有办法在Interface Builder中创建UIButtons并在viewDidLoad中获取对它们的引用?

2 个答案:

答案 0 :(得分:1)

尝试在

中执行此操作
- (void)viewDidLayoutSubviews{


}

加载所有子视图后调用此方法。希望这会对你有所帮助:)。

答案 1 :(得分:0)

所以我自己想出了一些这样的东西,使用了一些旧的Apple文档。它确实是一种常见的感觉。我将问题#1移到一个单独的问题上,开销较少,因为看起来没有人愿意阅读这个大问题。

最简单的方法是不为IBOutlet的集合添加UIButton s ...是等待它...使用IBOutletCollection

@property IBOutletCollection(UIButton) NSArray *buttons;

然后将UIButtons拖动并命令到xib中的文件所有者的IBOutletCollection中。我的代码更加清晰,而且我没有必要通过子视图等方式循环。

来源:

View Programming Guide for iOS - Locating Views in a View Hierarchy

  

存储对相关视图的引用是查找视图的最常用方法,并使访问这些视图非常方便。如果使用Interface Builder创建视图,则可以使用outlet将nib文件中的对象(包括代表管理控制器对象的File的Owner对象)相互连接。对于以编程方式创建的视图,可以在私有成员变量中存储对这些视图的引用。

看起来访问Interface Builder中创建的元素的唯一方法是通过IBOutlets / IBOutletCollections。

稍后会通过指向我的新问题的链接编辑此答案。

问题#1移到这里:Why is self.view.subviews an empty array in viewDidLoad?