views:

81

answers:

3

Hi,

I was wondering if anyone knew of any good online resources/tutorials for creating views and controllers programatically rather than via the interface builder. Everything I have looked at uses the interface builder and the created nibs, while the IB is ok I would like to have the option of developing these manually (both for practical reasons and get a good understanding of how it all fits together rather than the superficial one you get from dragging and dropping things).

My background is in java and I'm finding it slow and frustrating using the interface builder to develop views the way I would sometimes do them in Java, i.e. either

  • generate the source programatically from a domain model and then tweak the result if requried
  • use some meta-data and/or reflection and dynamically add the controls to the view

Also, once I have created a view is there anyway I can add it to the interface builder to make it available to use as a sub view on another view?

Thanks, Vic

A: 

I had the same issue a couple of months ago when I wanted to do all the iPhone development inside Emacs. To make a long story short: I'm not developing for the iPhone anymore :)

I'd still suggest you to check my question and some helpful answers here.

Federico Builes
He's not asking about a development environment, rather which way to build his views (programmatically or graphically). Has nothing to do with a text editor.
jbrennan
A: 

I typically don't use Interface builder too much for iPhone development. Usually I will create a view controller in code like this

MyUIViewControllerSubclass *controller = [[MyUIViewControllerSubclass alloc] initWithNibName:nil bundle:nil];
controller.someProperty = myModel;
[self presentModalViewController:controller];
[controller release];

Or something along those lines. Typically I create a subclass of UIViewController and that's where I layout my views and such. The views are subclasses of UIView (either things Apple provides like UIButton etc, or something I've created myself). If you read up on both UIViewController and UIView you should get a pretty good idea of how it works.

jbrennan
+1  A: 

The Interface Builder method creates "freeze-dried" objects that are re-created at runtime when you initialize the object from the NIB. It still does the same alloc and init stuff, using NSCoder objects to bring the objects in to memory.

If you want to have a view controller based on a particular NIB, you can then override the default init method and init it based on the NIB for that view controller. For example:

@implementation MyViewController
-(id) init {
    if (self = [super initWithNibName:@"MyViewController" bundle:nil]) {
        //other setup stuff
    }
    return self;
}

And when you want to display the MyViewController, you would simply call something like this:

- (void) showMyViewController {
    MyViewController *viewController = [[[MyViewController alloc] init] autorelease];
    [self presentModalViewController:viewController animated:YES];
}

Now, if you want to create your view manually instead of in Interface Builder, you don't have to change your -showMyViewController method at all. Get rid of your -init override, and instead override the -loadView method of your MyViewController to create it programmatically:

- (void) loadView {
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(320,460)];
    self.view = view;
    [view release];

    //Create a button
    UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [myButton addTarget:self action:@selector(pressedButton) forControlEvents:UIControlEventTouchUpInside];
    [myButton setTitle:@"Push Me!" forState:UIControlStateNormal];
    myButton.frame = CGRectMake(100,230,80,44);
    [self.view addSubview:myButton];
}

This example shows how to create the view and add a button to it. If you want to keep a reference to it, declare it the same way you would if you were using a NIB (without the IBOutlet/IBActions) and use self when assigning it. For example, your header might look like this:

@interface MyViewController : UIViewController {
    UIButton *myButton;
}

- (void) pressedButton;

@property (nonatomic, retain) UIButton *myButton;

@end

And your class:

@implementation MyViewController
@synthesize myButton;

- (void) loadView {
    //Create the view as above

    self.myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [myButton addTarget:self action:@selector(pressedButton) forControlEvents:UIControlEventTouchUpInside];
    [myButton setTitle:@"Push Me!" forState:UIControlStateNormal];
    myButton.frame = CGRectMake(100,230,80,44);
    [self.view addSubview:myButton];
}

- (void) pressedButton {
    //Do something interesting here
    [[[[UIAlertView alloc] initWithTitle:@"Button Pressed" message:@"You totally just pressed the button" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK",nil] autorelease] show];
}

- (void) dealloc {
    [myButton release];
    [super dealloc];
}
Ed Marty
Thanks for this, it's very helpful.
vickirk