Calling method in AppController from a ViewController - objective-c

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.

Related

Which method called when appdelegate.m transfers control to viewController

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.

Call Void on First View Controller from Second View Controller in Xcode

I am using Xcode 4.6.2 and have created a new Tabbed Application using apples template. I have placed a UIWebView on my First View Controller and loaded http://google.co.uk into it. On my Second View Controller I have created a button that, when pressed, will load http://google.co.uk/images into the Web View on the first controller. It is this bit I am stuck on, here is my code so far:
FirstViewController.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController {
IBOutlet UIWebView *mainWebView;
}
-(void)imagesURL;
#end
FirstViewController.m
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"First", #"First");
self.tabBarItem.image = [UIImage imageNamed:#"first"];
}
return self;
}
- (void)viewDidLoad
{
[mainWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://google.co.uk"]]];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)imagesURL {
[mainWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://google.co.uk/images"]]];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#import "FirstViewController.h"
#interface SecondViewController : UIViewController {
}
- (IBAction)imagesButton:(id)sender;
#end
SecondViewController.m
#import "SecondViewController.h"
#import "FirstViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Second", #"Second");
self.tabBarItem.image = [UIImage imageNamed:#"second"];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)imagesButton:(id)sender {
FirstViewController *view1 = [[FirstViewController alloc] init];
[view1 imagesURL];
}
#end
At the moment, when I press the Images button on the Second View Controller and switch back to the first, nothing happens at all. The webpage doesn't load. its like the Void isn't being called. What am I doing wrong?
The problem is in this line here FirstViewController *view1 = [[FirstViewController alloc] init]; - that is creating an entirely new copy of your view controller, which is not the one you started with in your first tab.
I think you would benefit from following some Objective C tutorials, or perhaps one of the iOS programming courses on iTunes U so that if something like this occurs again you have some more background.
There are many ways to do what you are trying to do, but one of the most straightforward is to have your second view controller talk to the tab view controller displaying it to get the first view controller. There should be reasonable documentation about how to do this in the iOS UITabViewController docs.

creating a UIViewController

I have a file, called Map:
#interface Map : UIViewController<MKMapViewDelegate> {
IBOutlet MKMapView *map;
}
In interfaceBuider Map starts when the tab is clicked:
Map opens a UITableViewController when clicking and this UITableView opens another UITableViewController.
So what I want now is in the last UITableViewController, when back button is pressed, back to map. I never change the tab, I'm always at "Plano"
so, in Navigation.m I have:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
And in my secondUITableView.m:
Navigation *aMap = [[Navigation alloc]initWithNibName:#"Map" bundle:nil];
[self.navigationController popToViewController:aMap animated:YES];
And what the error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'
How can I do this?
Thank you in advance
EDIT :
For back - root
[self.navigationController popToRootViewControllerAnimated:YES];
For back
[self.navigationController popViewControllerAnimated:YES];

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:.

Subclass of UIViewController shows black screen

I created a Subclass of UIViewController in my Project and linked it to a View which is modal-pushed by the "RootViewController". I made absolutely no changes to the derived class, but when the "SecondView" is pushed it turns black every time. If i link that view to the standard UIViewController class everything works fine?
Since the "SecondViewController" is derived from UIViewController I can only guess that the Problem has to do with the alloc/init function but I have no idea where to start.
I can provide the sample code I have in front of me now if necessary.
This is the derived subclass:
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self; }
- (void)loadView {}
- (void)viewDidLoad {
[super viewDidLoad]; }
- (void)viewDidUnload {
[super viewDidUnload];}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait); }
#end
Header:
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController
#end
- (void)loadView
{
// If you create your views manually, you MUST override this method and use it to create your views.
// If you use Interface Builder to create your views, then you must NOT override this method.
}
FYI, the comment is automatically generated too.
Change this:
- (void)loadView
{
// If you create your views manually, you MUST override this method and use it to create your views.
// If you use Interface Builder to create your views, then you must NOT override this method.
}
To this:
- (void)loadView
{
[super loadView];
// If you create your views manually, you MUST override this method and use it to create your views.
// If you use Interface Builder to create your views, then you must NOT override this method.
}
And it will work.
Try this
-(void)loadView
{
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
[view setBackgroundColor:[UIColor whiteColor]];
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(10, 50, 100, 100)];
[label setText:#"HAI"];
[view addSubview:label];
self.view = view;
}
If you are trying to get the view to load before it "shows" up during the segue from IB you might want to try something like this in the destination view controller.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view layoutIfNeeded];
}