It's confusing where to put init code - ios

I have a UIView, for which I implemented the init method. This works for me because I always initialize my UIViews with the simple code below.
MYView *view = [[MYView alloc] init];
[self.view addSubview:view];
[view setFrame:CGRectMake(0,0,99,99)];
QUESTION: Can this view be used with storyboards? or do I need to implement other "init" methods? Also, what happens if someone instantiates the view with initWithFrame? Do I need to implement all the "init" methods to handle all these cases?

Storyboard and XIB files will use the initWithCoder: methods.

Related

How to make a view controller without a xib or a storyboard vc identifier?

I wanted to know how to make a viewcontroller without the use of xib or storyboard. So in this case, I would be getting the viewcontroller as such
PopupViewController* vc = [[PopupViewController alloc] init];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];
I know it has to do something with overriding the init method since we are not using initWithCoder ?
I know I have to create a view and set it as the self.view for the PopupViewController, but I was wondering how I could do that.
EDIT: Yes it may be much easier just to make an xib file or add a view controller to the storyboard, this is to understand deeply how view controllers work.
The best place to init the view is in PopupViewController's loadView method. Something like:
- (void)loadView {
self.view = [MyViewClass new];
}
Then, in MyViewClass initWithFrame: method build all subviews and set constraints to it. If you're not using constraints, override layoutSubviews method.

custom uiview inside a uiview controller does not show ios

I have a UIView controller and a UIView called GCView.
If my code is just this :
self.view = [[GCView alloc] init];
I can see my custom view.
When I drag and drop a UIView in the storyboard, assign it to a property called customView
and use that code:
self.customView = [[GCView alloc] init];
nothing is shown.
I want to use the second approach, because it is more convenient to have some stuff inside the UIView created and handled dynamically, and the others to be statically inside the storyboard and handled in the UIViewController.
Make sure your view object in the story board is of class GCView. This will call initWithCoder: in your GCView class when the view loads. Once you have that, remove this:
self.customView = [[GCView alloc] init];
as the object will have already been initialized by the storyboard loading. Make sure all of your initialization calls in the GCView class are in initWithCoder: and not init.

How to make viewDidLoad called more than once

I know that viewDidLoad method may be called multiple times during UIViewController's lifecycle. But how is that possible? How to make it called more than once not calling it directly? I tried doing it this way:
UIView *view = [[UIView alloc] initWithFrame:self.view.frame];
view.backgroundColor = [UIColor greenColor];
self.view = view;
and whereas my view is actually changed, viewDidLoad is not called. Can anyone give an example?
The first time you access a viewController's view property the view will be created with loadView and then you will receive the viewDidLoad call.
You will not receive the viewDidLoad call again unless the view is destroyed - this may occur if your viewController goes off screen and UIKit decides to purge any view's that are not visible. Thus next time you access the view property it will notice it does not exist and again create one with loadView and then call viewDidLoad.
viewWillAppear method is an UIViewController method. Why you shouldn't call directly?
By the way there is no way to do that, while you assign an UIView to your self.view, id you are not doing it in the init or in the loadView or didLoad methods..
the life cycle is that:
init
loadView //change your view here
viewDidLoad
Then you present the view and:
viewWillAppear:
viewDidAppear:
if you want to change the view during your uiviewcontroller life cycle you should do:
UIView *view = [[UIView alloc] initWithFrame:self.view.frame];
view.backgroundColor = [UIColor greenColor];
[self viewWillAppear:NO]; //set to yes if you are making some kind of animation
self.view = view;
[self viewDidAppear:NO];
The will disappear and did disappear will be called according to the UIVIewController life cycle.

loadView: functions in UIView iOS

I don't understand the mechanism of loadView: function (this function is in UIView).
I created a project as below:
First, I created a iPhone's window-based project.
Then, I created a UIView subclass
Next, I created a UIViewController subclass, with no xib.
Lastly, in the loadView: function of the class I created in the third step, I designate the UIView object (in the class I created in the second step) as the view variable of the UIViewController object (in the third step).
If I omit the last step, and place the statement NSLog(#"test LoadView"); in the loadView: function, then when the project is run, the statement NSLog(#"test LoadView"); is invoked continuously, result in the run is overflow.
Please explain me! Thank you!
loadView: is only invoked when the view property is nil. Use this when creating views programmatically. default: create a UIView object with no subviews. For ex -
- (void)loadView
{
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
[view setBackgroundColor:color];
self.view = view;
[view release];
}
By implementing the loadView: method, you hook into the default memory management behavior. If memory is low, a view controller may receive the didReceiveMemoryWarning message. The default implementation checks to see if the view is in use. If its view is not in the view hierarchy and the view controller implements the loadView: method, its view is released. Later when the view is needed, the loadView: method is invoked again to create the view.
Not sure why you want to use loadView: but you can do just as much in viewDidLoad:
Reference -
Why is this iPhone program not calling -loadView?
loadView
Hope this helps.

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

When working with views and view controllers in an iPhone app, can anyone explain the difference between loadView and viewDidLoad?
My personal context, is that I build all my views from code, I do not and will not use Interface Builder, should that make any difference.
I've found that often when I add init code to loadView, I end up with an infinite stack trace, so I typically do all my child-view building in viewDidLoad...but it's really unclear to me when each gets executed, and what is the more appropriate place to put init code. What would be perfect, is a simple diagram of the initialization calls.
Thanks!
I can guess what might be the problem here, because I've done it:
I've found that often when I add init code to loadView, I end up with an infinite stack trace
Don't read self.view in -loadView. Only set it, don't get it.
The self.view property accessor calls -loadView if the view isn't currently loaded. There's your infinite recursion.
The usual way to build the view programmatically in -loadView, as demonstrated in Apple's pre-Interface-Builder examples, is more like this:
UIView *view = [[UIView alloc] init...];
...
[view addSubview:whatever];
[view addSubview:whatever2];
...
self.view = view;
[view release];
And I don't blame you for not using IB. I've stuck with this method for all of Instapaper and find myself much more comfortable with it than dealing with IB's complexities, interface quirks, and unexpected behind-the-scenes behavior.
loadView is the method in UIViewController that will actually load up the view and assign it to the view property. This is also the location that a subclass of UIViewController would override if you wanted to programatically set up the view property.
viewDidLoad is the method that is called once the view has been loaded. This is called after loadView is called. It is a place where you can override and insert code that does further initial setup of the view once it has been loaded.
viewDidLoad()
is to be used when you load your view from a NIB and want to perform any customization after launch
LoadView()
is to be used when you want to create your view programmatically (without the use of Interface Builder)
Just adding some code examples to demonstrate what NilObject said:
- (void)loadView
{
// create and configure the table view
myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped];
myTableView.delegate = self;
myTableView.dataSource = self;
myTableView.scrollEnabled = NO;
self.view = myTableView;
self.view.autoresizesSubviews = YES;
}
- (void)viewDidLoad
{
self.title = #"Create group";
// Right menu bar button is to Save
UIBarButtonItem *saveButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:self action:#selector(save)];
self.navigationItem.rightBarButtonItem = saveButtonItem;
[saveButtonItem release];
}
To prevent an infinite loop from happening when you read self.view, call the class' super implementation when you load a view. The super implementation will allocate a new UIView for you.
- (void) loadView {
[super loadview];
// init code here...
[self.view addSubView:mySubview1]; //etc..
}
The easiest way to use loadView is to make some type of base view controller, like MyBaseViewController which is subclass of UIViewController. In it's loadView method create view in this way:
-(void) loadView {
if ([self viewFromNib]) {
self.view = [self viewFromNib];
} else {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
}
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.view.backgroundColor = [UIColor whiteColor];
}
And when you need to make some view controller you just use subclass of MyBaseViewController and in it's loadView controller you just call [super loadView] like this
//sucblass loadView
-(void) loadView {
[super loadView];
//rest of code like this..
UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame];
[self.view addSubview:myLabel];
[myLabel release];
}
loadView() is called when your controller is asked to create its self.view. You can do it by yourself like
self.view = [UIView alloc] init...];
Or your controller's parent UIController class has already a method name -loadView() which initializes your self.view into blank view. Then you can call
[super loadView];
I really recommend the second approach as it encourages the inheritance. Only if your view controller is not directly inherited from UIViewController.
The definition given by Apple on viewDidLoad mentioned that it is called after the controller’s view is loaded into memory. To put it in a simple term, it is the first method that will load.
You might be thinking under what condition will this method being fully utilized? The answer is, basically whatever you wanted the app to load first. For instance, you might want a different background color, instead of white, you could perhaps choose blue.

Resources