I am pushing viewControllerB from A as,
if(!self.controller2){
self.controller2 = [[viewControllerB alloc] initWithNibName:#"viewControllerB" bundle:nil anUser:self.idUser aidioma:self.idioma];
}
[[self navigationController] pushViewController:self.controller2 animated:NO];
Then, I pop B to A. Now need to push A again but initializing again B or calling function on B in order to pass new vars. Following options could be valid but I've got no success,
Release controller2 and = nil, but IF sentence is not executed because controller2 still active!
Call function on viewControllerB in order to pass new pars without init but function is not called.
What am doing wrong? Thanks.
The following code ensures that every time you navigate from A -> B -> A (via the Nav Controller's back button) -> B, B's init method is called every time (I'm using ARC here... if you aren't, let me know and I'll edit the example):
AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
viewControllerA *vcA = [[viewControllerA alloc] initWithNibName:#"viewControllerA" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vcA];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}
viewControllerA's button action method:
- (IBAction)moveForward:(id)sender {
// change this line to call your custom init method.
viewControllerB *vc = [[viewControllerB alloc] initWithNibName:#"viewControllerB" bundle:nil];
[self.navigationController pushViewController:vc animated:YES];
}
Try to Use NSNotificationCenter check this Link which Describes it Properly.
Send and receive messages through NSNotificationCenter in Objective-C?
use This Code in your Class A viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveTestNotification:)
name:#"TestNotification"
object:nil];
Use the following Code in your Class B pop function.
[[NSNotificationCenter defaultCenter]
postNotificationName:#"TestNotification"
object:self];
Related
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
The code I am using
NSLog(#"before Navigate to second activity");
Signature *temp = [[Signature alloc]initWithNibName:#"Signature" bundle:nil];
[self.navigationController pushViewController:temp animated:YES];
NSLog(#"after Navigate to second activity");
On console,both the log statements are getting printed, but my app is not navigating me to the next View.Please correct me.
if you are not using a UINavigationController on your app you can not call pushViewController, use presentViewController:animated:completion: instead:
[self presentViewController:temp animated:YES completion:nil];
for more information check the documentation
The log messages would show anyway, so no surprise there. Add a callback to the delegate for that navigation controller (you must first set a delegate of course) for
navigationController:didShowViewController:animated:
There you can make sure that the viewController passed (make sure Signature is a ViewController instance).
i think your application is not with navigationController so in AppDelegate.m file assign rootViewController like this..
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
RootViewController *viewController1 = [[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil] autorelease];
UINavigationController *navviewController=[[UINavigationController alloc]initWithRootViewController:viewController1];
self.window.rootViewController = navviewController;
[self.window makeKeyAndVisible];
return YES;
}
after that check its working..
CreditsViewController *viewController = [[CreditsViewController alloc] init];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];
you can try with above code
I'm having trouble coding a button to go to the previous page. I was able to do it to go to the next page thinking if I did the same thing but changed it a bit it would work in reverse. Unfortunately, I come up with a lot of errors I can't resolve because it won't allow me to use the release function.
This is this the code that helps it to work going to the next page fine:
#import "ViewController.h"
#implementation ViewController
-(IBAction)btnClicked:(id) sender
{
//add the view of the view controller to the current View---
if (menuView==nil) {
menuView =
[[MenuView alloc] initWithNibName:#"MenuView"
bundle:nil];
}
[self.view addSubview:menuView.view];
}
-(void)dealloc {
[menuView release];
[super dealloc];
}
How do I do it so that a back button will go to the previous page though.
It's pretty simple, use this :
-(IBAction)back:(id) sender
{
[menuView.view removeFromSuperview];
}
But, I would suggest not using addSubview: for many views as it would be complex way to do. Use UINavigationController as #Paul.s suggested.
The way you are doing this is not quite correct and I would suggest doing some reading to get familiar with iOS programming.
Your program structure should be: create a navigation controller (2) to manage the stack of view controllers giving it a viewController (1) to act as it's root.
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// 1
FirstViewController *firstViewController = [[FirstViewController alloc] init];
// 2
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[firstViewController release]; firstViewController = nil;
self.window.rootViewController = navigationController;
[navigationController release]; navigationController = nil;
[self.window makeKeyAndVisible];
return YES;
}
This will display your first view controller inside a UINavigationController. A UINavigationController is responsible for managing a stack of UIViewController's and giving you UI to navigate back down the stack as well as calling all the appropriate presentation related methods on a UIViewController at the correct times e.g. viewDidLoad. You should check out The View Controller Programming Guide for lots of info
Then inside your first view controller you do something like this to respond to the button:
- (IBAction)buttonClicked:(id)sender;
{
SecondViewController *secondViewController = [[SecondViewController alloc] init];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release]; secondViewController = nil;
}
This creates a new view controller and pushes it onto the stack.
I want to start my app up with a different Xib. How would I do this?
Thanks
If you're using interface builder:
Under SupportingFiles, in -info.plist, look for a key named "Main nib file base name". Change that to the XIB you want it to load first
You can also take that entry out of the plist altogether an in main.m give it your appDelegate's name:
int retVal = UIApplicationMain(argc, argv, nil, #"HelloViewAppDelegate");
Then in your appDelegate, you can manually load your first view controller based on your code and logic. Personally, I like this better because it's much clearer to - here's my delegate and code to load it. It doesn't have all the bindings in IB I need to remember.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
CGRect screenBounds = [[UIScreen mainScreen] applicationFrame];
CGRect windowBounds = screenBounds;
windowBounds.origin.y = 0.0;
// init window
[self setWindow: [[UIWindow alloc] initWithFrame:screenBounds]];
// init view controller
_mainViewController = [[MainViewController alloc] init];
[[self window] addSubview:[_mainViewController view]];
[self.window makeKeyAndVisible];
return YES;
}
EDIT:
Answering your comment below. You pasted this invalid code:
// init view controller
ViewController = [[ViewController alloc] init];
[[self window] addSubview:[ViewController view]];
That's not valid. you need an instance variable name. By referring to it as "ViewController" your attempting to call class member variables. If your class is called ViewController then it should be:
// notice the instance myviewController is of type ViewController
ViewController *myViewController = [[ViewController alloc] init];
// notice calling view against instance (myViewController)
[[self window] addSubview:[myViewController view]];
At this point, if it's not compiling you need to edit your question and paste your main.m and appDelegate exactly as is into the question.
The MainWindow.xib file is just a shell that provides the application's UIWindow. While you can put a UIViewController in MainWindow.xib, you can also just have an unconnected UIViewController outlet on your app delegate and pick which nib to load at runtime in your application:didFinishLaunchingWithOptions: method, e.g.:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)options {
if (case1)
self.viewController = [[[MyViewController1 alloc] initWithNibName:nil bundle:nil] autorelease];
else if (case 2)
self.viewController = [[[MyViewController2 alloc] initWithNibName:nil bundle:nil] autorelease];
else
self.viewController = [[[MyViewController2 alloc] initWithNibName:nil bundle:nil] autorelease];
[window addSubview:self.viewController.view];
[window makeKeyAndVisible];
return YES;
}
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...
}