I'm trying to call a method in the view controller from the app delegate, but Xcode says No known class method for selector 'myMethodHere'. Here's my code:
AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[..]
[MainViewController myMethodHere];
[..]
return YES;
}
MainViewController.m:
-(void) myMethodHere {
[..]
}
I would try
MainViewController * vc = [[MainViewController alloc]init];
[vc myMethodHere];
[vc release];
Make sure to import your MainViewController in your app delegate .m file
make sure you add "myMethodHere" to your MainViewController .h file
You are trying to call a class method when you want to call an instance method. If the view controller is the root view controller, then you should be able to call it thus:
UIWindow *window = [UIApplication sharedApplication].keyWindow;
MainViewController *rootViewController = window.rootViewController;
[rootViewController myMethodHere];
If it's not the root view controller then you'll have to find some other way of getting hold of the instance and then calling the method as in the last line above.
If you want to access to a view controller on a story board, you may use this block of code from the AppDelegate:
MainViewController *rootViewController = (MainViewController*)self.window.rootViewController;
[rootViewController aMethod];
Remember to add the import.
In Swift, you can write it like this
UIApplication.sharedApplication().keyWindow?.rootViewController?.yourMethodName()
Try to write
-(void) myMethodHere;
in MainViewController.h
Related
I'm experiencing a few issues when trying to call a method from another class. Here's my code
Appdelegate.m
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
if ([url isFileURL]){
RootViewController *theview = [[RootViewController alloc] init];
[theview handleOpenURL:url];
}
return YES;
}
RootViewController.h
#interface RootViewController : UIViewController <UIWebViewDelegate>{
IBOutlet UIWebView* mainwebView;
}
- (void)handleOpenURL:(NSURL *)url;
#property (nonatomic, retain) UIWebView* mainWebView;
RootViewController.m
- (void)handleOpenURL:(NSURL *)url{
NSLog(#"Method handleOpenURL completed")
[mainwebView setDelegate:self];
[self.mainwebView loadRequest:[[NSurLRequest alloc] initWithURL:url];
[self performSelector:#selector(handleIt) withObject:nil afterDelay:3.0];
}
- (void)handleIt{
docView *docController = [[docView alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:docController animated:YES];
}
So, basically I'm trying to update a UIWebView and then present a modal view controller once the appdelegate calls handleOpenURL. The problem is that both of these things (updating webview and presenting view controller) refuse to work in the method handleOpenURL. They work perfectly fine in viewdidload, which makes me think it has something to do with the method being called from appdelegate.
The webview simply refuses to respond when accessed from the handleOpenURL method, and when I present the modal view controller I get the error
Warning: Attempt to present ... whose view is not in the window hierarchy!
But, again the modalview works fine when presented from viewdidload (using the time delay selector)
An explanation to why this is happening or a workaround would be great, thanks for your help.
You have to #import "docView.h" in your RootViewController.m.
Warning: Attempt to present ... whose view is not in the window hierarchy!
The warning states the view is not recognized, meaning you don't have access to the class properly, if it's not importing, then you didn't set up the code in docView.m properly.
If that doesn't work, than i need more info to help solve your problem.
Edit for Clarification:
The app-delegate is called at the start and when pointed to, not
constantly.
You should call it from when the modal view loads, a method
pointer([self myFunctionNameHere];) would work just fine.
So it's that your not accessing the app-delegate properly.
I don't think you should even be calling it from the app-delegate,
call it from your .m.
Calling it from your main(.m) file would solve everything.
I'm now writing a registration screen before my tabBar shows up. My idea is to show my registration screen through this method (no dismiss function for now):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
Register *registerView = [[Register alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:registerView animated:YES];
return YES;
}
Which is in AppDelegate.m
Unfortunately it doesn't work. Could you help me solve this please?
presentModalViewController:animated: is a method of the UIViewController class. Since the app delegate is not a view controller, you can't send it this method. To display your first view controller on screen, assign it to your app's main window's rootViewController property:
self.window.rootViewController = registerView;
so in my app delegate I am trying to present a modalViewController from a UITabBarController, by doing the following:
self.tabBarController = [[UITabBarController alloc] init];
LoginViewController* loginViewController = [[LoginViewController alloc] init];
loginViewController.delegate = self;
[self.tabBarController presentModalViewController:loginViewController animated:NO];
[loginViewController release];
and the delegate defined in the app delegate is:
- (void)userDidLogin:(LoginViewController *) loginViewController
{
NSLog(#"DELEGATE CALLED, DISMISSING");
[self.tabBarController dismissModalViewControllerAnimated:NO];
}
Here's my LoginViewController:
protocol LoginViewControllerDelegate;
#interface LoginViewController : UIViewController <MBProgressHUDDelegate>
{
id<LoginViewControllerDelegate> delegate;
}
#property (assign) id<LoginViewControllerDelegate> delegate;
#end
#protocol LoginViewControllerDelegate
- (void)userDidLogin:(LoginViewController *) loginViewController;
#end
The issue is that this (userDidLogin:(LoginViewController *) loginViewController) is never called... why is this?
I have called the following in my LoginViewController implementation and this is called
[self.delegate userDidLogin:self];
UPDATE:
I got the delegate called now. The issue now is that when I call [self.tabBarController dismissModalViewControllerAnimated:YES] it doesn't dismiss the modal view controller.
You didn't post any code from LoginViewController, but within that class's code you need to add the following lines when you are ready to dismiss it (perhaps when the user clicks the "Login" button and the login is successful).
if (delegate && [delegate respondsToSelector:#selector(userDidLogin:)])
[delegate performSelector:#selector(userDidLogin:) withObject:self];
UPDATE:
I think I understand what the issue is here. According to Apple's documentation, when you call presentModalViewController:animated: the method sets the value of the "modalViewController" property of UIViewController (in this case your UITabBar). However that property only maintains a weak reference to the modalViewController. That's important because you initialize the LoginViewController, pass it in to presentModalViewController:animated: and then you release it. Since presentModalViewController:animated: is not retaining a strong reference to the LoginViewController, the UITTabBar is unable to dismiss it later on. In fact I'm surprised what you have done is not resulting in an EXC_BAD_ACCESS crash. I suggest you remove the "[loginViewController release]" statement and instead release it after you call "[self.tabBarController dismissModalViewControllerAnimated:NO]"
I am seeing a strange app behaviour when I try to push some view controller from uitableviewcontroller subclass.
Let me explain it first. I have created main nib which is linked to rootViewController (appDelegate) that is inside navigationController. In that nib a have added a UITableView and a custom UITableViewController subclass News_TableViewController like it's shown in the screenshot:
When I try to execute the code bellow I get nothing:
My_WebView *webView = [[My_WebView alloc] initWithNibName:#"My_WebView" bundle:nil];
[self.navigationController pushViewController:webView animated:YES];
Then I checked self.navigationController object but i gives me NULL:
NSLog(#"OBJ: %#",self.navigationController);
How is that I am not geting the reference to the navigationController despite of my custom class actually lives under navigationController ?
Thanks
As you've mentioned, News_TableViewController is a UITableViewController, hence a UIViewController. I think you did'nt initialize the navigationController! A recommended way is to init the navigationController in your appDelegate class' delegate method as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
RootViewController *rootViewController = [[RootViewController alloc]init];
_navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
where RootViewController is the News_TableViewController class.
So here is my problem:
I have an AppDelegate with a navigationController:
[self.window addSubview:navigationController.view];
In there i put an presendModalViewController:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[self navigationController] presentModalViewController:passwordViewController animated:YES];
}
I want an PasswordView which takes the Password and tells the UIView in the NavigationController that he can begin his work with catching information from the internet, with a nice MBProgressHUD Loading View.
I tried to build up an Delegate but it does´t work because the instance of my UIView is build up in the Navigation controller.
I there a way to tell my UIView which is in my NavigationController that Password was given and back that the Password was right und say back with:
[self.parentViewController dismissModalViewControllerAnimated:YES];
to remove this View?
There is an App named iOutbank which has what I want to assume...
Add a delegate to your view controller class that is invoked when a valid password has been entered. Something like this in your login view controller would work:
#protocol LoginDelegate
- (void)loginSucceeded;
#end
#interface LoginViewController : UIViewController
{
id<LoginDelegate> delegate;
}
}
Next, set the delegate of your password view controller to be the app view controller class. To do this your app delegate class needs to implement the protocol you've defined for your login delegate, so in the app delegate header and implementation files:
#interface MyAppDelegate : NSObject <LoginDelegate>
{
// App delegate interface stuff
}
#implementation MyAppDelegate
{
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Create myLoginViewController
[myLoginViewController setDelegate:self];
// Display login view controller
}
- (void)loginSucceeded
{
// Dismiss login view controller
// Do other stuff
}
}
When your app delegate class gets notified that the password has been entered, then you can dismiss the password view controller and do whatever it is you want to do next.
#Tim Dean, thank you very much you helped me to help myself and think about my problem.
So this is how i ended up doing it:
I made an instance of my PasswordView in My tableView:
- (void)viewDidLoad
{
self.passwordView = [[PasswordViewController alloc]init];
[passwordView setPasswordViewDelegate:self];
[self.navigationController presentModalViewController:self.passwordView animated:YES];
}
Put in there my Delegate:
#interface TableView : UITableViewController <PasswordViewDelegate>
{
PasswordViewController *passwordView;
}
And get my Delegate method from my PasswordView:
-(void)loginPressed
{
NSLog(#"Login Pressed");
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
And now I can use my logic of my TableViewClass.
I love stack overflow!
Greetings and I hope there is somebody I shall helped with my solved problem, I'm going to sleep now....