Which method called when appdelegate.m transfers control to viewController - objective-c

I learn the ObjC program flow, so far I understand that chain begins in main.m->UIApplicationMain->AppDelegate->ViewController
The point I don't understand is to which method inside the ViewController the AppDelegate class transfers the focus...
I feel it is critical to understand this topic, so would be thankful for any clarifications.
I have this code of Appdelegate.m -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
MasterViewController *masterViewController = [[MasterViewController alloc] init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController: masterViewController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
and inside the ViewController there are these methods -
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES animated: NO];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear: animated];
}
and others methods...
My questions are
To what method AppDelegate transfers control in MasterViewController. And does the control come back after MasterViewController "finished" its job or it is just looped?
How MasterViewController gets the xib name for initialisation (is it the same name as m file? i.e. what does it mean - nibNameOrNil bundle:nibBundleOrNil)
I see navigation controller involvement, however I don't understand how it is connected to viewcontroller....
If you catch my misunderstanding points - please be patient to explain... I feel that after this point I will be able to start...

(1) You're thinking about the logical flow in a procedural sort of way. The main run loop dispatches events down the responder chain. Your MasterViewController doesn't really 'finish'.
(2) The designated initializer for UIViewController is initWithNibName:bundle:. Your use of init here will not touch any associated nib file. If you wish to initialize MasterViewController from the nib, then you must use the designated initializer, e.g.
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"your-nib-name-goes-here" bundle:nil];
nibNameOrNil and nibBundleOrNil are just parameter names for the method. It's a tip to you that they may be nil. Take a look at the documentation for how the method behaves when those params are nil.
(3) UINavigationController is a subclass of UIViewController that presents content hierarchically. In this case, the application's window's root view controller is a navigation controller. In turn, that navigation controller's root view controller is your MasterViewController instance.
The documentation for UINavigationController describes it well.

Related

How to know the design file assigned to view controller

I'm launching a view controller in my app with this code :
MyViewController *myViewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:myViewController animated:YES];
However I don't know what design file my viewcontroller use to add a simple label to it. I don't know if it uses any design file(story board). I have story board file and I have assigned its class to my controller but does the above code launch the controller with the story board?
Thanks
Your myViewController does not connect to any xib file(design file)
You could connect your design file using this construct method of UIViewController.
- (instancetype)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
For example:
MyViewController *myViewController = [[MyViewController alloc] initWithNibName:#"Your_Design_File_Name" bundle:nil];
[self.navigationController pushViewController:myViewController animated:YES];

Why sometimes initWithNibName not called?

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
Everything works fine. The code above is standard written by compiler. Nothing strange. I put breakpoints there in my viewControllers just to see how things go.
Sometimes the function is called. Sometimes it's not.
'
In all cases things work fine. But what would be the circumstances where that function is not called?
Yes, I am using XIB for all those viewControllers.
I notice that viewControllers directly under the navigationViewController is the one where initWithNibName doesn't break. I wonder why.
When your NSViewController is defined in a xib file (usually as an IBOutlet), initWithNibName:bundle: is not called, rather initWithCoder: gets called. This is the case when you use Interface Builder to set your NSViewController as part of UITabBarController(for UIViewController) or UINavigationController, and almost always when using Storyboards.
Or you can try this one also:
myViewController *objMyViewController = [[MyViewController alloc] initWithNibName:#"WebViewController_iPhone" bundle:nil];
objMyViewController.managedObjectContext = self.managedObjectContext;
navController = [[UINavigationController alloc] initWithRootViewController:objMyViewController];
[self.window setRootViewController:navController];
[window makeKeyAndVisible];

Calling method in AppController from a ViewController

I'm trying to build a Cocoa app for OSX Lion.
I have this line in my AppController code:
self.viewController = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil appController:self];
[_view addSubview:[_viewController view]];
[[_viewController view] setFrame:[_view bounds]];
LoginViewController looks like this:
#implementation LoginViewController
#synthesize appController = _appController;
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil appController:(AppController *)appController {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[self setAppController:appController];
NSLog(#"Appcontroller init: %#", _appController);
}
return self;
}
- (IBAction)login:(id)sender {
NSLog(#"Appcontroller login: %#", _appController);
}
The login method is connected to a button click.
Log:
2012-05-23 12:45:49.574 QBLoader[3241:503] Appcontroller init: <AppController: 0x7fe2ab210440>
2012-05-23 12:45:52.085 QBLoader[3241:503] Appcontroller login: (null)
Why is the second log line null?
Since you indicated there is more than one instance of LoginViewController, I would check your xibs to see if you have created an object of that type anywhere. In particular I would start with the xib where you wire up the -login: action. If you only have one instance of AppController, a common method is to create the object in your MainMenu.xib and attach it to an outlet in your app's delegate. Then you can use something like [[NSApp delegate] appController] to access it.

Access Root UINavigationController from Pushed UIViewController

I've run into a problem with my Project.
Every time I try to access my UINavigationController from a Pushed UIViewController, I get "(null)" as a return.
So this is my project is structured:
1. AppDelegate.m initalises UINavigation Controller
2. UINavigation Controller starts with Welcome Page
3. Welcome Page Pushes New UIViewController on Button Press
4. UIViewController returns (null) when self.navigationController called
OK, so here's some code, in my Welcome Page I'm calling this:
MyClass *theChatRoom = [[MyClass alloc] initWithNibName:#"ChatRoom" bundle:nil];
[theChatRoom setTitle:[unitCode text]];
[self.navigationController pushViewController:theChatRoom animated:YES];
Which works fine, it pushes the new View Controller.
But then in MyClass.m :
#implementation MyClass
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
NSLog([NSString stringWithFormat:#"%#",self.navigationController]);
}
return self;
}
This returns (null)
What am I doing wrong?
According the documentation, the navigationController of UIViewController:
This property is nil if the view controller is not embedded inside a
navigation controller.
That's said, if you access the navigationController before embedding into the UINavigationController(not push yet), it will return nil. So you can access it in the viewDidLoad but no in - (id)initWithNibName:bundle:.

Calling a new view: problems "hiding instance variable"

I am trying to call a subview after a button is clicked on my root controller. The warnings appear in my AppDelegate (code is below), but I included the method from my root controller on how I call this new subview also in case that too has a problem.
the alerts that continue to come up are that the local declaration of navController hides an instance variable.
When I launch the application (which used to open fine) it now simply exits out...
#import "SEM2REDOAppDelegate.h"
#import "SEM2REDOViewController.h"
#implementation SEM2REDOAppDelegate
#synthesize window;
#synthesize navController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window makeKeyAndVisible];
SEM2REDOViewController *firstController = [[SEM2REDOViewController alloc]
initWithNibName:#"SEM2REDOViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:firstController];
[self setNavContorller:navController];
[window addSubview:[navController view]];
[navController release];
[firstController release];
return YES;
}
then here is the method inside of my first view controller
- (IBAction)chooseFirstMeeting:(id)sender {
SelectRotationController *selectView = [[SelectRotationController alloc]
initWithNibName:#"SelectView" bundle:[NSBundle mainBundle]];
[selectView.navigationItem setTitle:#"Select First Meeting"];
[self.navigationController pushViewController:self.selectRotationController animated:YES];
self.selectRotationController = selectView;
[selectView release];
}
I know this may be an extremely simple question but I've just started this. doing an intensive study on programming in high school as an added course so I'd really appreciate any help!
Rename navController
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:firstController];
into something else. You can do this automatically by control-clicking word "navController", choosing "Refactor" from context menu, and then "Rename...".
Explanation:
The problem, I believe, in your local variable navController having the same name as instance variable under synthesized declared property navController.
Edit:
Also, this seems to be a typo:
[self setNavContorller:navController];
Correct:
[self setNavController:navController];