I am using the iPhone toolchain on Linux and so I have no Interface Builder. So how could I layout my view in my ViewController subclass? For example, I want a UITextView in the middle of the screen? Should I do this in the loadView
or viewDidLoad
. Do I also have to set the view for the ViewController subclass to itself?

- 53,877
- 76
- 193
- 251
-
Think that a lot of object have a "center" property. it's a CGPoint and it's very usefull when you want to center object in the space. It's better than using the frame property where you need to calculate things. – Vinzius Sep 25 '10 at 20:29
3 Answers
It is not an easy job to layout all the view using code. Here are some code:
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake (100, 100, 100, 100)];
[self.view addSubview:textView];
The frame is the place (the first and second argument is x and y coordinator) and the size (the third and fourth argument is width and height of the text view).
Using this way, you can add any view into your class. Some of the view is built in and you don't have to draw yourself, some of them is not, and you need to subclass UIView and override drawRect.
You should do this in viewDidLoad when your main view controller is finished loading

- 18,639
- 11
- 76
- 110
I've written an open source project that does exactly this:
https://github.com/charlesmchen/WeViews
Here's another project that you might find useful:

- 209
- 3
- 9
I usually build the entire view hierarchy in the loadView method and perform additional setup in the viewDidLoad, for example to set up the subviews content to reflect the data associated to the view controller. The important thing is to set the view controller view outlet in the loadView method.
@synthesize label; // @property(nonatomic,retain) UILabel *label declared in the interface.
-(void)loadView {
// Origin's y is 20 to take the status bar into account, height is 460 for the very same reason.
UIView *aView = [[UIView alloc]initWithFrame:CGRectMake(0,20,320,460)];
[aView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
[aView setAutoresizeSubviews:YES];
// The 150x50 label will appear in the middle of the view.
UILabel *aLabel = [[UILabel alloc]initWithFrame:CGRectMake((320-150)/2,(460-50)/250,150,50)];
// Label will maintain the distance from the bottom and right margin upon rotation.
[aLabel setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin];
// Add the label to the view hiearchy.
[self setLabel:aLabel];
[aView addSubview:aLabel];
// Set aView outlet to be the outlet for this view controller. This is critical.
[self setView:aView];
// Cleanup.
[aLabel release];
[aView release];
}
-(void)viewDidLoad {
// Additional and conditional setup.
// labelText is an istance variable that hold the current text for the label. This way, if you
// change the label text at runtime, you will be able to restore its value if the view has been
// unloaded because of a memory warning.
NSString *text = [self labelText];
[label setText:text];
}
-(void)viewDidUnload {
// The superclass implementation will release the view outlet.
[super viewDidUnload];
// Set the label to nil.
[self setLabel:nil];
}
The biggest difficulty is probably understanding how IB settings map to UIView variables and methods, for example the autoresizing mask. Apple's UIView and UIViewController class references are full of useful informations.

- 447
- 8
- 17
-
I am not using interface builder, so would the first line of your code sample even be necessary? I know I can omit the IBOutlet. Could I also omit the property declaration and therefor the synthesize declaration? – Mohit Deshpande Oct 10 '10 at 12:58
-
It depends. Any element you add as a descendant of the view outlet is retained and released with it, so it is not necessary. However, if I need to access a subview anywhere in the controller, I would rather have it as a convenient instance variable and set it to nil in the viewDidUnload and release it in the dealloc, like the label in the above sample. This way I don't end up with a pointer to a deallocated object. You can also just assign it manually or use a (assign)property, or assign a tag to it and recover it when needed, but setting it as a (retain)property is safer and cleaner imo. – sigsegv Oct 11 '10 at 08:59