I have a view controller which get called from several places, and the first time it is called, awakeFromNib is called, but viewDidLoad is not called. viewWillAppear and viewDidAppear are called each time.
Also, the view (a UITableView subclass) functions correctly, except that anything within viewDidLoad is obviously not implemented.
loadView is not overridden in this view controller.
the code used to override viewDidLoad and awakeFromNib:
- (void)awakeFromNib
{
// Configure for self sizing cells:
self.tableView.estimatedRowHeight = 44;
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.allowsSelectionDuringEditing = YES;
self.clearsSelectionOnViewWillAppear = NO;
self.navigationItem.title = nil;
self.navigationItem.rightBarButtonItem = nil;
printf("\n awake from nib \n \n ---------- \n");
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.tableView.allowsSelectionDuringEditing = YES;
}
how is it possible that awakeFromNib is called but viewDidLoad is not, and how can I fix it?
edit: I received an answer that helped fixed it, however I would like to know why it happened, because it may be related to a bug in my app.
thank you.
This was a bit of a stab in the dark in a comment but it turned out to resolve the issue.
Ensure to call [super awakeFromNib] in the overridden method.
Related
While referring a sample code i found this snippet can any explain why it is used.
- (id)init
{
self = [super init];
if (self) {
[[self view]setBackgroundColor:[UIColor redColor]];
}
return self;
}
and what is the difference between the following snippet.
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
}
init and viewDidLoad both are completely different.
viewDidLoad called, when the view is loaded into memory, this method called once during the life of the view controller object. It's a great place to do any view initialization.
init method is an initializer method. Cocoa has various types of intializer. To learn more, please check the link,
https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization.html
I created a method that sets the title of a button based on a value.
This method needs to be called when opening the viewController and maybe refreshed when the controller appears again.
So i created the method and I called that method in viewDidLoad and viewDidApper but it seems to be called only when I change page and turn back to the view controller.
Why?
My code is
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self controlloRichieste];
......
}
-(void)viewDidAppear:(BOOL)animated{
[self controlloRichieste];
}
-(void)controlloRichieste{
//Numero richieste di contatto
NSString *numeroRichieste = #"1";
if([numeroRichieste isEqual:#"0"]){
[_labelRequestNumber setTitle:#"Nessuna" forState:UIControlStateNormal];
} else {
_labelRequestNumber.titleLabel.text = numeroRichieste;
_labelRequestNumber.tintColor = [UIColor redColor];
}
//Fine Numero richieste di contatto
}
You can also move that code to viewWillAppear so that it gets called each time it appears.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self controlloRichieste];
}
I see the problem now, try the other way around
-(void)controlloRichieste{
//Numero richieste di contatto
NSString *numeroRichieste = #"1";
if([numeroRichieste isEqual:#"0"]){
[_labelRequestNumber setTitle:#"Nessuna" forState:UIControlStateNormal];
} else {
_labelRequestNumber.tintColor = [UIColor redColor];
[[_labelRequestNumber titleLabel]setText:numeroRichieste];
}
//Fine Numero richieste di contatto
}
Change set the button color, before you change its titleLabel's text
I created a demo PROJECT for you, hope it's helpful!
When you open view first time the viewDidLoad is called and the viewDidAppeare.
The viewDidAppeare is called every time when the view is opened, when you push or present other view controller and go back to the maine one viewDidAppeare is called.
You should call:
[super viewDidAppear:animated];
The viewDidLoad is called just when the view is loaded and after that when it's deallocated and it needs to be allocated again. So mostly when you push or present other view controller and go back to the maine one viewDidLoad is not called.
I have a UITableViewController and don't want to use a storyboard.
As far as I know, the UITableViewController takes care of initialising the UITableView, connecting it to its dataSource and delegate. This works very well in my case.
I would now like to change the class of the UITableView to a custom class (BVReorderTableView). This would be easily done in IB. However, once I do this programmatically, my UITableView is empty, that is it seems to be disconnected from its source and delegate.
Here is what I do in my init of the UIViewController:
-(id)init
{
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
// Custom initialization
self.tableView = [[BVReorderTableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
self.tableView.dataSource = self;
self.tableView.delegate = self;
}
What am I doing wrong?
You should implement this in viewDidLoad instead of init, because of the ViewController lifecycle. At viewDidLoad he already has all of the objects that are going to get used, which isn't necessarily true during init.
You can check this question for more information on ViewController life cycles.
:)
Please set your UITableView in viewDidLoad method not in initmethod. In init method view will initialize itself before subviews contained within it.
Hope this helps
I am trying to create a view controller with a map as the header (working), but my tableview will not populate and the cellForRowAtIndexPath method is never getting called. Any suggestions?
Code is on a gist here: https://gist.github.com/ohwutup/5229232
Here are some screenshots of my IB settings:
In your viewDidLoad method, add this.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.title = #"Nearby";
self.tableView.tableHeaderView = _mapView;
self.tableView.delegate = self;
self.tableView.dataSource = self;
...
}
needed to do [self reloadData] in the completion block of my json request.
Your tableview's datasource and delegate should be your view controller, DOViewController. Then you tableview will populate correctly. Change the outlets in IB to point to your view controller class.
In the ViewController's interface, I have
#property int count;
and in the implementation, I have
#synthesize count;
-(id) init {
self = [super init];
if (self) {
self.count = 100;
}
return self;
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"%i", self.count++);
}
but for some reason, the first time self.count got printed, it is 0 but not 100?
One of various -init methods will be called on your UIViewController, depending on whether it came out of a .xib, storyboard, or is alloc'd manually somewhere else in your code.
A better place to put this kind of initialization is in -viewDidLoad, something like this
- (void)viewDidLoad {
[super viewDidLoad];
self.count = 100;
}
Put a NSLog or debugging breakpoint in your init method and I suspect you'll find it isn't called. If you look at UIViewController, you'll see other initialization methods (e.g. if you're using a NIB, it would invoke initWithNibName:bundle:). If it's via a storyboard, it can differ. See the discussion of initialization in Apple's View Controller Programming Guide for iOS.
A better place for general view controller configuration is viewDidLoad.
Change it to:
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
self.count = 100;
}
return self;
}
The view is actually getting created by the XIB, which is 'decoding' it or unboxing it. When this happens, the XIB calls initWithCoder: