Programatically adding a tableView, viewDidLoad not called - ios

I would like to use my viewDidLoad function in my tableViewController.
How can I make viewDidLoad run in my controller?
tableViewController = [[TableViewController alloc] init];
UITableView *tableView = [[UITableView alloc] init];
tableViewController.view = tableView;
....

From Apple documentation:
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
So you can try to instantiate it from NIB or overwrite the loadView method. Another step from Apple documentation:
If you cannot define your views in a storyboard or a nib file, override the loadView method to manually instantiate a view hierarchy and assign it to the view property.

viewDidLoad will be called when the view is actually loaded, which will happen after you present your view controller, by, e.g.:
adding it to a navigation controller,
adding it to a tab bar controller,
presenting it modally.
This is the missing bit in your code. If you explain how you would like to present your view controller, I may help further. Also, have a look at this: Presenting View Controllers.
(I assume the fact that you tried to override the view property of your table view controller was just an attempt "to make things work" -- but you do not need to do anything about that, the view controller will be correctly set up with a table view inside of it).

tableViewController = [[TableViewController alloc] init];
tableViewController.tableView // This is your newly generated tableview
viewDidLoad will be called after you assign the tableView to another parentview

Related

viewDidLoad (and loadView) is not fired after the view controller is pushed into navigation controller

viewController's view is not loaded just after that viewController is pushed into navigation controller.
This is my code snippet.
- (void)myMethodInClassA {
// window's root view controller is navigation controller
UINavigationController *naviCtrl = (UINavigationController*)[UIApplication sharedApplication].keyWindow.rootViewController;
MyViewController *myVC = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
[naviCtrl pushViewController:myVC animated:NO];
// at this point, myVC's view is NOT loaded
}
When I call myMethodInClassA, myVC's viewDidLoad is called AFTER that method returns. I'd expected that myVC's view is loaded just after navigation controller's pushViewController:animated: is called and before myMethodInClassA returns.
When exactly view controller's view is loaded? Apple's documentation just says it is loaded when it is first accessed. It's a bit ambiguous. why doesn't navigation controller's pushViewController: access view controller's view?
p.s. sorry for initial ambiguous question.
Pushing a view controller (VC) onto a navigation controller's stack makes the VC into a child view controller of the navigation controller (which is a container view controller). Creating such a child-parent relationship is a distinct step which does not cause the child VC's view to be loaded immediately. Rather the container VC loads the view at a later time. I believe there is no explicit specification for what "later" means - usually it will be when the container VC has decided that the time has come to integrate the child VC's view into the container VC's view hierarchy. But basically it simply happens at the discretion of the container VC's implementation.
That being said, anyone can force a VC's view to be loaded by simply accessing the VC's view property. For instance, in your code you could add this line
myVC.view;
which would trigger loadView and then viewDidLoad in MyViewController.
However, in your case if MyViewController needs to react to the event that it has been associated with a container VC, then it would be better to override one (or both?) of the following methods in MyViewController:
- (void) willMoveToParentViewController:(UIViewController*)parent
{
// write your code here
}
- (void) didMoveToParentViewController:(UIViewController*)parent
{
// write your code here
}
You need to be aware, though, that willMoveToParentViewController and didMoveToParentViewController are also invoked when MyViewController is popped from its parent navigation controller's stack. You can detect that this is the case by checking the parent argument for nil.
(Swift 2)
Since this question doesn't have an accepted answer...
What I ended up doing is create a convenience init at the child view controller:
convenience init() {
self.init(nibName: "ChildViewController", bundle: nil)
//initializing the view Controller form specified NIB file
}
and in the parentViewController's viewDidLoad():
let commentsView = CommentsViewController()
self.addChildViewController(commentsView)
self.momentsScrollView.addSubview(commentsView.view)
commentsView.didMoveToParentViewController(self)
As stated above,viewDidLoad gets called once when a view is pushed,you might want to do your stuff in viewWillAppear or viewDidAppear.
Ya if that ViewController will be already pushed in navigationController stack then ViewDidLoad method will not be called again.
First time when you will push that ViewController then viewDidLoad will be called.
So if you need that your some functionality is to be executed every time then implement it in viewWillAppear method because it will be called every-time you push your viewController.
Hope it helps you.
are you pushing the view controller for the first tym?if YES then only viewDidLoad() of the controller will be called and if its already pushed and this is not the first tyn then viewWillAppear () will be called.(or) if you are making a new instance every tym u push it then viewDidLoad() will be called.
I find that I have to call loadViewIfNeeded()
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621446-loadviewifneeded

Adding a child view controller and changing its label

I got a view controller named IntroViewController in my storyboard and I want to add this as a child to another view controller like this:
IntroViewController *introViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"View1"];
[introViewController.textLabel setText:#"test"];
[self addChildViewController:introViewController];
On the IntroViewController I've put a label named textLabel on it in the storyboard, if I run the program it works and shows me the view controller, but the text doesn't get changed. Any idea how I can fix this?
When you instantiate a view controller from a storyboard, the view is not loaded until it is actually presented on screen. At the point in your code you have posted introViewController.textLabel is nil.
One option you could do is add a property to your IntroViewController class and instead set that:
introViewController.initialText = #"test";
Then, inside -viewDidLoad of your IntroViewController the label will be instantiated so you can make the call:
[self.textLabel setText:self.initialText];
It is also worth noting that most of the time it would be recommended to have a view controller be the one to set values on the views it owns, rather than some other view controller.

viewWillAppear not invoked for subview controller

I have an odd case -- a view controller that creates its own view in loadView and which is then added to an existing view.
Here is the code that creates and adds the VC:
self.doneButtonViewController = [[DoneButtonViewController alloc] init];
[self.view addSubview:self.doneButtonViewController.view];
This code is executed in viewDidLoad of the "parent" VC.
The odd thing is that the viewWillAppear method of the added VC is never invoked (nor is viewDidAppear), but the viewWillDisappear method of the added VC is invoked (at the appropriate time), just as one would expect.
Any clue as to why viewWillAppear is not getting invoked?
The application isn't aware of the subview's view controller if you do this, you need to introduce view controller containment to make the root view controller aware. Doing so will handle any events like this.
Because loadView could be called more than once pre iOS 6, I'd advise creating the view controller within init, and then add the subview within loadView. It should be like this:
- (id)init {
...
self.doneButtonViewController = [[DoneButtonViewController alloc] init];
[self addChildViewController:self.doneButtonViewController];
[self.doneButtonViewController didMoveToParentViewController:self];
...
}
- (void)loadView {
...
[self.view addSubview:self.doneButtonViewController.view];
...
}
See "Implementing a Container View Controller" at http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
As for me, adding child view controller in parent view controller can solve the problem that "viewWillAppear" of the child view controller not get called.

How did iOS set UIViewController's view frame before shown?

I am not familiar with iOS UIViewController's detail implement. I have the following code to create a new UIViewController and show it, but the frame I set during initWithFrame method does not worked, the controller's view always is fullscreen(320*480).
UIViewController *viewController = [[UIViewController alloc] init];
// view
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 140, 130)];
viewController.view = view;
[view release];
AppController *app = (AppController*)[[UIApplication sharedApplication] delegate];
UINavigationController *nav = [app navController];
[nav pushViewController:viewController animated:YES];
[viewController release];
I search releative thoughts in apple developer documents, but I found nothing useful for this. How did UIViewController deal with its view frame property before show it? Where can I found useful documentation.
Thank you.
Update: In fact, the code is from cocos2d-iphone DirectorTest: https://github.com/cocos2d/cocos2d-iphone/blob/release-2.0-rc1/tests/DirectorTest.m#L143
You've got this all wrong - you really need to read (and understand) Apple's UIViewController docs:
View Controller Catalog
View Controller Programming Guide
View Controller Reference
If you're creating a view in code for a view controller, you should do it in the view controller's loadView method.
Directly from Apple's documentation:
Creating a View Programmatically
If you prefer to create views programmatically ...
you do so by overriding your view controller’s loadView
method. Your implementation of this method should do the following:
Create a root view object. The root view contains all other views
associated with your view controller. You typically define the frame
for this view to match the size of the app window, which itself should
fill the screen. However, the frame is adjusted based on how your view
controller is displayed. See “View Controller View Resizing.”
You can use a generic UIView object, a custom view you define, or any
other view that can scale to fill the screen.
Create additional subviews and add them to the root view. For each
view, you should do the following:
Create and initialize the view. For system views, you typically use
the initWithFrame: method to specify the initial size and position of
the view. Add the view to a parent view using the addSubview: method.
Assign the root view to the view property of your view controller.

PushViewController doesn't do anything

This is the first time I'm trying to implement navigation from a tableView cell to another tableView using UINavigationController and it doesn't work for me.
I'm NOT using nib file and I have a simple tableView that I present it in a modal dialog in my app, it works fine, now I added the disclosureInidcator to one of it's cell, to make the user enable to choose from a fixed number of options available from another list(tableView). For this purpose I have another class that makes the second tableView. the problem is now navigation from the cell(contains disclosure icon)in first tableview to second tableView doesn't do anything, no error, no nothing. I guess the way I setup the navigation controller would be wrong, the code doesn't fall in delegate, or datasource of the second class at all.
in First TableView in method : didSelectRowAtIndexPath I tried to catch that row, then call the second tableView like this:
mySecondViewController *secondVC = [[[mySecondViewController alloc] initWithStyle:UITableViewStyleGrouped ] autorelease];
UINavigationController *navCont = [[UINavigationController alloc] initWithRootViewController: self];//not sure the first controller should act as the root controller?
[navCont pushViewController:secondVC animated:YES]; //it does nothing, no error,...
the second tableViewcontroller class contains all delegate and datasource methods, and initialization method:
- (id)initWithStyle:(UITableViewStyle)style
{
if ((self = [super initWithStyle:style])) {
}
return self;
}
and declared in interface as:
#interface stockOptionViewController : UITableViewController {
}
I tried to play with viewDidLoad, but didn't help.
Please help me cause I have no clue and all sample codes found is based on using nib files.
Thank,
Kam
Your navigation controller should be the root view controller of the app delegate's window, and the first view controller should be the root view controller of the navigation controller, then you can push new controllers onto it.
Please see the documentation for UINavigationController.
At the moment, you are creating a navigation controller but not putting it anywhere, so asking it to push new view controllers is a little pointless. You have the right code, just not in the right order.
You can present view control modally without nav controller
mySecondViewController *secondVC = [[[mySecondViewController alloc] initWithStyle:UITableViewStyleGrouped ] autorelease];
[self presentModalViewController:secondVC animated:YES];
UINavigationController should be the root view controller. In the current code, navCont is not on the view stack, so it won't work. Instead of pushing myFirstViewController in your appDelegate, push the UINavigationController to the stack and add myFirstViewController as its root view controller.

Resources