I am developing an application which has about 8 views and use navigation controller to navigate through. The first view is a main menu.
What i want is (of each view) to pop to the main view if the user press the home button (App did enter background).
I know the AppDelegate methods applicationDidEnterBackground and applicationWillEnterForeground.
And i know the method popToRootViewControllerAnimated called from the navigation controller.
I have tried to use popToRootViewControllerAnimated in applicationDidEnterBackground.
Like:
[self.window.rootViewController.navigationController popToRootViewControllerAnimated:YES];
But this does not work.
Can you please let me know what is the best option for this job?
i think you try NSNotificationCenter like this:
inside applicationDidEnterBackground and applicationWillEnterForeground put this
[[NSNotificationCenter defaultCenter] postNotificationName:#"popToRoot" object:nil];
and in your rootViewController's viewDidLoad (that always appears on app launch) add this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(popToRootViewControllerAnimated) name:#"popToRoot" object:nil];
Then create a method in your rootViewController:
- (void)popToRootViewControllerAnimated
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
Whenever the application will start first time, NSNotificationCenter will initialize for name popToRoot and prepare a method popToRootViewControllerAnimated for this.
And when application will go to background, NSNotificationCenter will pass a massage #"popToRoot" to rootViewController's popToRootViewControllerAnimated method and viewcontroller will pop to rootview
have you tries it like this :-
[self.navigationController popToRootViewControllerAnimated:YES];
replace your navigationController name with navigationController here.
Edit:-
in AppDelegate.h file
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
UINavigationController *navMain;
}
#property (nonatomic, retain) UINavigationController *navMain;
in AppDelegate.m file
#synthesize navMain;
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
self.navMain = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = self.navMain;
[self.window makeKeyAndVisible];
return YES;
}
-(void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"applicationDidEnterBackground");
[self.navMain popToRootViewControllerAnimated:YES];
}
try edited anwser
crate a propery for UINavigationController in your AppDelegate class. In applicationDidEnterBackground: method call the popToRootViewController method by using the UINavigationController Property. For Suppose your propery name is navigationController then
[self.navigationController popToRootViewControllerAnimated:YES];
First: you should check wether the rootviewcontroller is a navigationController. Because self.window.rootViewController.navigationController is often nil.
Why?
Because the navigationController of a navigationController is 'nil'. Mostly, I set my rootViewController to be a navigationController
Secondly:
You shouldn't do animated stuff when your application is about to quit. You should do it not-animated
popToRootViewControllerAnimated:NO
Related
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
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.
In application:didFinishLaunchingWithOptions: I initialize a UINavigationController. Later, I add the UINavigationController to the window:
[self.window addSubview:navigationController.view]
This all works fine. Now I added local notifications to my app and when the user responds to one, I would like to present a UIViewController. So I thought I could override application:didReceiveLocalNotification: and in there, use my navigationController:
[navigationController pushViewController:someVC animated:YES];
However, this does not work. I did some debugging and noticed that while navigationController is not nil, navigationController.view has no superview, so I assume it is not being displayed.
So, my question is: where should I push my UIViewController so that it gets displayed?
In your AppDelegate.h add this:
//Under where you have <UIKit/UIKit.h>
extern NSString *localReceived;
In your AppDelegate.m add this:
//All the way on top where you import your viewControllers
NSString *localReceived = #"localReceived";
In your AppDelegate.m in the - (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotification;
method add this:
[[NSNotificationCenter defaultCenter] postNotificationName:localReceived object:self];
Make sure that your viewController is a navigationController
If it's not, do the following -- Add this piece of code to your - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions:
UINavigationController *nvcontrol = [[UINavigationController alloc] initWithRootViewController:viewController];
[window addSubview:nvcontrol.view];
[window makeKeyAndVisible];
Now -- in your viewController.m add this to your -viewDidLoad function
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(localAction) name:localReceived object:nil];
Make a -(void) localAction and in that method add your navigationController code to push to the next View Controller!
Hope that works for you. Works like a charm for me
So here it is, another solution with a different approach. It worked like a charm for me. check it out:
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotification{
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
CustomViewController *cvc = (CustomViewController *)[storyboard instantiateViewControllerWithIdentifier:#"CustomVC"];
AnotherViewController *avc = (AnotherViewController *)[storyboard instantiateViewControllerWithIdentifier:#"AnotherVC"];
avc.someValue = #"Passing a value"; //Optional
UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
nav.viewControllers = [NSArray arrayWithObjects:cvc,avc, nil];
[(UINavigationController *)self.window.rootViewController popToViewController:avc animated:TRUE];
[[UIApplication sharedApplication] cancelLocalNotification:localNotification];
//Cancel Just for not showing it anymore on the notifications list...
}
I'm trying to display an "About Page" in my application when pressing a button, but when I press the UIButton, the NSLog(#"Button pressed") is called, but the view won't load. Here is my code:
- (IBAction)pushAbout {
NSLog(#"Button pressed");
AboutView * aboutView = [[AboutView alloc] initWithNibName:#"AboutView" bundle:nil];
[self.navigationController pushViewController:aboutView animated:YES];
[aboutView release];
}
I've seen this code in an example, but it was called in a UITableViewController instead of an ordianry UIView controller.
The class files "AboutView" were created as UIViewController subclass. They were created and left untouched
A guess: Your view is not in a UINavigationController, hence
self.navigationController
is actually nil, and nothing happens.
The solution would be to place the main view in a nav controller, and adding the nav controller's view to your application's main window.
A simple way of doing this:
In your app delegate, change
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
to
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions
(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UINavigationController* navController = [[UINavigationController alloc]
initWithRootViewController:self.viewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
Or similar. Note that this is just to get you started, and maybe not the nicest way of doing it. (I assumed you've just created a view-based application in xcode.)
Yes you don't have a UINavigationController set.
Add
NSLog(#"nav? %#", self.navigationController);
to your action and you'll see that it dumps (null).
However, the AboutView.xib works fine if you enter this code:
[self presentModalViewController:aboutView animated:YES];
instead of
[self.navigationController pushViewController:aboutView animated:YES];
The view will show up. In you zipped example the AboutView.xib didn't contain a label, so don't wonder if it turns out to be a white page.
You can dismiss the presented modal view by using
[self dismissModalViewControllerAnimated:YES];
in your AboutViewController.
To get your hands on a UINavigationController I suggest creating an app with the Navigation-Based Application template.
How can I accomplish the following:
When my app loads a UIView will show 4 buttons
Clicking on a button will load a UITabBarController (not a UIView with a UITabBar) that can display multiple views.
This seems challenging to me, because in order for me to use the UITabBarController I need to add this to the window's subview in my appDelegate. By doing so, my app automatically will load with the UITabbarController in the root view.
You don't need to add the UITabBarController in the application delegate, that's just the most common way to use it. You can have your initial view use a simple UIViewController, then when the button is pressed load the UITabBarController (either programmatically or from a nib), and then display it.
The following is an example of what might be in your app delegate:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// viewController is a UIViewController loaded from MainWindow.xib with a button that calls loadTabBarController
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (IBAction) loadTabBarController {
self.tabBarController = [[[UITabBarController alloc] initWithNibName:#"MyTabBarController" bundle:nil] autorelease];
[viewController.view removeFromSuperview];
[window addSubview:tabBarController.view];
}