【问题标题】:Why is self.view.subviews an empty array in viewDidLoad?为什么 viewDidLoad 中 self.view.subviews 是一个空数组?
【发布时间】:2015-01-24 19:05:02
【问题描述】:

我使用 Interface Builder 创建了一堆 UI 元素,并使用 IBOutlets 将它们连接到我的 ViewController。

但是,当我尝试在 ViewController 的 viewDidLoad 方法中迭代 self.view.subviews 时,我发现 subviews 数组是空的。

  • ViewController.xib:

    UIView
    |
    - UILabel
    - UIButton
    - // ... more stuff
    - UIToolbar
    
  • ViewController.m:

    #import "ViewController.h"
    @interface ViewController ()
    // Interface elements
    @property IBOutlet UILabel *titleLabel;
    @property IBOutlet UIButton *button1;
    // ... etc
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // BREAK_POINT
    
        // ... code to wire up the UIButtons to dynamically created objects
    }
    
  • BREAK_POINT 处的调试器输出:

    (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>>
    

任何想法为什么当 UIButtons 等已被初始化并正确连接到 IBOutlets 时 self.views.subviews 为空?


编辑 1:我将“MainView.xib”重命名为“ViewController.xib”并删除了我的ViewController.m 中的loadView 实现,我仍然看到相同的self.view.subviews 行为。

【问题讨论】:

  • 你不应该碰–loadView方法,因为你可能会弄乱加载会话——就像你现在正在做的那样——但即使你会碰它,你也必须调用@ 987654334@,否则你会破坏加载链——就像你现在正在做的那样。
  • 好吧,我想不出任何其他方式来加载我的 xib。我开始以编程方式创建所有内容,然后切换到使用 xib。这是我让它工作的唯一方法。
  • 遵照@wolffan 的建议,重命名了xib,去掉了loadView 代码。我仍然看到相同的行为。
  • FWIW,在我设法通过代码中的init 实例化视图控制器之后,空subviews 的效果相同——这是一个不正确的 q&d 疏忽——而不是通过情节提要,来自那个控制器应该来的地方……
  • …确实,有一个related question针对不同样式的实例化视图控制器来寻址子视图

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


【解决方案1】:

尝试这样做

- (void)viewDidLayoutSubviews{


}

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

【讨论】:

  • 确实有效,谢谢!阅读 Apple 的 iOS 库上的 ViewController 生命周期,现在这更有意义了。
【解决方案2】:

我相信这可能与您加载视图的方式有关。 在 viewControllers 上,如果您的 nib 和 VC 在 IB 上正确链接,则无需使用 loadView 或 NSBundle 来 loadNib。

此外,如果您将 nib 命名为 ViewController,则指定的 init 会为您正确加载它。 如果您使用 loadView,您必须自己加载所有视图树,而不仅仅是主视图。

查看链接:iPhone SDK: what is the difference between loadView and viewDidLoad?

【讨论】:

  • 好的,所以我将 MainView.xib 重命名为 ViewController.xib 并从 ViewController.m 中删除了 loadView...该应用程序仍然运行良好。但是,我仍然看到 self.views.subviews 的相同行为
  • 我之前实际上已经阅读过@Marco 的答案,我熟悉这种差异,并且拥有无限堆栈跟踪的东西。我不知道 Interface Builder 在 ViewController 生命周期中的位置。
  • 好的@Vidur 不是访问子视图数组,而是直接从它们的属性中获取视图?他们在吗?编辑:抱歉没有阅读您的编辑。看起来很奇怪...你能显示 IB 的屏幕和连接吗?
  • 我根据@AugustinePA 的回答弄清楚了。感谢您的帮助
【解决方案3】:

如果您将设置代码移至 viewWillAppear 会怎样?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2021-10-12
    • 2012-08-26
    相关资源
    最近更新 更多