4

In AppDelegate, I want to create a UIViewController subclass and add it's view. The viw itself will be specified in code - there is no nib.

Based on the apple docs, I should use

initWithNibName:nil bundle:nil];

and then in loadView of the controller, I add my subviews etc.

However, the follwing test code below does not work for me. I modelled the AppDelegate code on Apple's PageControl demo, simply because my app will implement a similar structure (specifically a base controller to manage a paged scroll view, and an array of other controller's to build the pages).

But I suspect my AppDelegate code is the problem, since logging proves that initWithNibName:: and loadView both fire. The app as below runs, but the screen is blank. I am expecting a green view with a label.

AppDelegate

        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        ScrollerController *controller = [[ScrollerController alloc] initWithNibName:nil bundle:nil];
        [self.window addSubview:controller.view];
        [self.window makeKeyAndVisible];
        return YES;
    }

ScrollerController (the UIViewController subclass)

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)loadView{
    CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
    UIView *contentView = [[UIView alloc] initWithFrame:applicationFrame];
    contentView.backgroundColor = [UIColor greenColor];
    self.view = contentView;

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(40, 40, 100, 40)];
    [label setText:@"Label created in ScrollerController.loadView"];
    [self.view addSubview:label];
}
Ben Packard
  • 26,102
  • 25
  • 102
  • 183

2 Answers2

5

Try to use: self.window.rootViewController = controller; instead of [self.window addSubview:controller.view];

Note, that you should also @synthesize window; and create it self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • I am synthesizing the window, but why do I need to create it myself? - I only ask because the demo project from apple doesn't do this. – Ben Packard May 30 '12 at 20:32
  • it depends, are you creating everything programatically, or are you using the window that is in a nib. If you are not using the window in a nib, than you need to create the window programatically as Sulthan suggests. – timthetoolman May 30 '12 at 20:38
4

Instead of initWithNibNamed:, just use alloc and init or any of the other designated initalizers for the view controller. Here is an example from a project

hoverViewController=[[BDHoverViewController alloc] initWithHoverStatusStyle:BDHoverViewStatusActivityProgressStyle];
self.window.rootViewController=hoverViewController;
[self.window makeKeyAndVisible];

also, the correct form( for now anyways) for adding the root view controller to the window in the app delegate is like this:

self.window.rootViewcontroller=controller;
[self.window makeKeyAndVisible];

You don't need to add the view to the window. The above code does it automatically.

Good luck,

T

timthetoolman
  • 4,613
  • 1
  • 22
  • 22
  • The second half of this looks good, but do you have any source for the first part? I only ask because I have read (I think in the apple docs) that the correct way to initialize a controller without a nib is to use nil. I'll see if I can find where I read that. – Ben Packard May 30 '12 at 20:27
  • I read it on SO, so not necessarily authoritative: 2a. Loading the view programmatically If you choose to override -loadView, you can create a view, subviews, other viewControllers, and any connections between these objects in any way you please. Of course, this means that you are also responsible for memory management with respect to the objects that you create. If your subclass overrides -loadView, it should be initialized using nil for both nibName and bundle. SOURCE: http://stackoverflow.com/questions/5107604/can-somebody-explain-the-process-of-a-uiviewcontroller-birth-which-method-follo – Ben Packard May 30 '12 at 20:30
  • 1
    yes you are correct, I did a quick look at the docs and that is correct. To be safe, I try to use initWithNibNamed: method only if I am using a method. I've updated my answer. – timthetoolman May 30 '12 at 20:35