Initializing Views(button, label, etc) in -init or -loadview

329 Views Asked by At

Im curious, where is the best option to allocate/init, set attributes of views (uibutton, uilabel, uitextfield, initializing variables, etc).

This is in regards to developing an app strictly programatically. I see some cases where these views have been allocated/init in the class -init method, but then other times i see other views set in the -loadview method.

Can anyone provide some clarity about this? And maybe some abstract examples of when the best time to do it for either method would be.

Thanks

2

There are 2 best solutions below

11
Larry Pickles On

Here's a quick comment on this:

-SubClass a UIView, smash all your UI elements into that view, well as many as you can at least. Import this subclassed view's header into your view controller's implementation file

-In your view controller, typecast your view controller's view like so:

-(HHYSignUpViewFirstPhase*)contentView
{
    return (id)[self view];
}

-Invoke the loadView method

-(void)loadView
{
    [self setView:[HHYSignUpViewFirstPhase new]];
}

-In your viewdidLoad, you can now set handlers to buttons and such from your subclassed UIView by calling to "[self contentView]" like so:

  -(void)viewDidLoad
    {
        [super viewDidLoad];
        [self setTitles:@"Sign Up"];
        [[[self contentView] nameField] setDelegate:self];
        [[[self contentView] emailField] setDelegate:self];
        [[[self contentView] passwordField] setDelegate:self];
        [[[self contentView] signupButton] addTarget:self action:@selector(signupPressed) forControlEvents:UIControlEventTouchUpInside];
    }

Now you have it all set up, you just need to add methods to handle events from the button, for example in the view did load from your subview that you subclassed:

-(void)signupPressed
{
   ///do work
}

UIVIew subclass:

HHYSignUpViewFirstPhase.h

@interface HHYSignUpViewFirstPhase : UIView

@property (nonatomic) UIButton * signupButton;
@property (nonatomic) UITextField * emailField;
@property (nonatomic) UITextField * nameField;
@property (nonatomic) UITextField * passwordField;

@end

HHYSignUpViewFirstPhase.m

#import "HHYSignUpViewFirstPhase.h"

@implementation HHYSignUpViewFirstPhase

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self == nil)
        return nil;


          //do work, set up buttons, constraints, etc, etc.


         return self;
}
@end

Essentially, what I'm saying here is that in the subclassed UIView you can initialize the UIView and set up all its constraints and EVERYTHING, frames included and then in the load view method of your UIViewController, you then call to this view and typcast the view of the UIViewController. So, sometimes you do the set up in the init, sometimes you do it in the load view, it depends on what you are trying to do, but this is how you set this up in a pure programmatic fashion with separation of duties, encapsulation, and all tied together in an MVC framework -- all work is separated into classes, and all controllers control a single class.

http://matthewmorey.com/creating-uiviews-programmatically-with-auto-layout/

and this

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html#//apple_ref/doc/uid/TP40007457-CH10-SW36

3
Ewan Mellor On

The -init* family of functions would be a good place to initialize simple properties, e.g. strings, numbers, and the like. The initializer runs just after the memory for the object is allocated, and if you have something that can be initialized there then you should do it there.

For UIViewController instances, you probably have to wait until the nib has been loaded before you can initialize everything else. If you've got images that need to be placed inside subviews, or fonts that need configuring, or whatever, then you need to have the nib loaded first. -viewDidLoad is the best place for that stuff.

For UIView instances (or subclasses like UITableViewCell), you need to wait for the nib to be loaded too. You can use -awakeFromNib in that case.