6

I've created a bunch of UI elements using Interface Builder and hooked them up to my ViewController using IBOutlets.

However, when I try to iterate through self.view.subviews in my ViewController's viewDidLoad method, I find that the subviews array is empty.

  • 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
    }
    
  • Debugger output at 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>>
    

Any ideas why self.views.subviews is empty when clearly the UIButtons, etc have been initialized and wired up to the IBOutlets correctly?


Edit 1: I renamed "MainView.xib" to "ViewController.xib" and removed the loadView implementation in my ViewController.m, and I'm still seeing the same self.view.subviews behavior.

Vidur
  • 1,442
  • 2
  • 17
  • 37
  • 2
    you should not touch the `–loadView` method, becase you just can mess up the loading session – as you are doing it right now – but even if you would touch it, you have to call the `[super loadView];`, otherwise you break the loading chain – as you are doing it right now. – holex Nov 26 '14 at 12:40
  • Okay, I couldn't figure out any other way to load my xib though. I started off creating everything programmatically and switched to using a xib after. And this was the only way I could get it to work. – Vidur Nov 26 '14 at 12:42
  • Followed @wolffan's recommendation below and renamed the xib and got rid of the `loadView` code. I'm still seeing the same behavior. – Vidur Nov 26 '14 at 12:50
  • FWIW, same effect of empty `subviews` after I had managed to instantiate a view controller via `init` in code—a q&d oversight which wasn't proper—, and not via the storyboard, from where that controller should have come… – B98 Mar 23 '16 at 18:30
  • …Indeed, there is a [related question](http://stackoverflow.com/questions/26131693/instantiate-view-controller-from-storyboard-vs-creating-new-instance) addressing subviews in view of different styles of instantiating view controllers – B98 Mar 23 '16 at 18:51

3 Answers3

4

Try to do that in

- (void)viewDidLayoutSubviews{


}

This method get called after loading all the subviews. Hope this will help you :)

Augustine P A
  • 5,008
  • 3
  • 35
  • 39
  • 1
    That did work thanks! Read up on the ViewController life cycle on Apple's iOS library and this makes much more sense now. – Vidur Nov 27 '14 at 10:52
0

I believe it might be related on the way you load the view. On viewControllers there's no need to use loadView, or NSBundle to loadNib if your nib and your VC are properly linked on IB.

Also if you name your nib as the ViewController, the designated init will load it properly for you. If you use loadView you have to load all the view tree yourself, not only the main view.

See link: iPhone SDK: what is the difference between loadView and viewDidLoad?

Community
  • 1
  • 1
wolffan
  • 1,084
  • 10
  • 15
  • Okay, so I renamed `MainView.xib` to `ViewController.xib` and removed `loadView` from `ViewController.m`...and the app still works great. However, I'm still seeing the same behavior with self.views.subviews – Vidur Nov 26 '14 at 12:48
  • I've actually read @Marco's answer on there before, and I'm familiar with that difference, and had that infinite stack trace thing. I don't know where Interface Builder comes into the picture of the ViewController's lifecycle. – Vidur Nov 26 '14 at 12:54
  • Ok @Vidur instead of accessing the subview array you get directly the views from their properties? are they there? EDIT: sorry didn't read your edit. Seems weird... can you show screen of IB and the connections ? – wolffan Nov 26 '14 at 14:23
  • I figured it out based on @AugustinePA's answer. Thanks for your help – Vidur Nov 27 '14 at 10:53
0

What if you move your setup code to viewWillAppear?

Adam Kaump
  • 715
  • 4
  • 14