how to send string value with popToViewController - iphone

I am using navigationcontroller. i have (Root,A,B,C,D) class. i want to sand a string test value Class D to Class A via popToViewController.
Please give me suggestion.
Thanks

UINavigationController maintain the list of all pushed controller in viewControllers and the root controller always reside at 0.
MyAController *myController = (MyAController *)[self.navigationController.viewControllers objectAtIndex:0];
myController.myText = #"My String" ;
[self.navigationController popToViewController:myController animated:YES];

You might want to rethink your design, but since you haven't given enough information for me to suggest how, you could just try this:
A *aController = (A *)[myNavController rootViewController];
[aController setMyString:#"your string here"];
[myNavController popToRootViewControllerAnimated:YES];

Make that string as property of class a then you need to access that object of the view A from navigation stack in class D.
And then access that property for using.
If Class A is rootView then jtbandes answers helps you otherwise pick it up from stack code some thing like this
if([self.navigationController.viewControllers count]>3)
A *aController=(A *)[self.navigationController.viewControllers objectAtIndex: [self.navigationController.viewControllers count]-4];
if your navigation is A->B->c->D
then you can access c by [self.navigationController.viewControllers count]-2 similarly B by -3 A by -4.

There are several approaches to achieve this.
Using Notifications.
Using Delegates.
Using Outlets/Properties.

You could also create a ControllerA instance var in your ControllerB and then pass the ControllerA (self) to ControllerB(ex: by a method) before call pushViewController from A to B. You can do the same from B to C...etc; i think the best solution is that of Jhaliya in case you want to work with navigationControllers.

Related

Detect the viewcontroller

i have a application which is handling lots of functions and also having lots of navigations.
I am using lots of BOOLs inside my application. I know its not efficient. So I want to remve these BOOLs to create more efficient and clean application.
This is my question. For a Example lets say I have 3 UIViewControllers.
Test1 , Test2, Test3
I need to navigate to Test3 from both Test1 and Test2 view Controllers . Also if I navigate to Test3 View Controller from Test1, I need to execute one method and, if I navigate to Test3 from Test2, I need to Execute another method.
Currently what i am doing is, I am Using Globals.h and Globals.m classes to over come this problem. I create a BOOL in Globals and enable that BOOL value in Test1 and, I checked that BOOL value inside Test3 and execute the method i want.
This is just an example. I got lots of view controllers and lots of behaviors for the application. So I create lots of BOOLs inside Globals and used them in different Classes. So this is a pain to handle lots of bools in one application and it not good too. So can any one please help me how to overcome this problem.
Thanks in advance :)
you can also check class with NSObject method isKindOfClass.
You can also find example given in that method explaination.
Here you can compare the object is which kind of class, and accordingly you can perform your operation.
For that you can pass your self reference to Controller3 every time and you can store it with id type.
Hope this will help you in your code.
Like #mrunal said you can use isKindOfClass. just figured I through in some code.
// self is Test3
if ([self.presentingViewController isKindOfClass:[Test1ViewController class]]) {
// Run your method for Test1 - Test 3 here.
}
If you're pushing or presenting a modal you'll need to grab the actual viewController since presentingViewController will be a UINavigationController. This is how I do it.
// self is Test3
if ([self.presentingViewController.childViewControllers.lastObject isKindOfClass:[Test1ViewController class]]) {
// Run your method for Test1 - Test 3 here.
}
Try using the viewControllers property of the navigation controller.
UINavigationController reference
What I mean is, when a view controller loads that you need a specific action done based on where it came from grab the view controllers array and look at the object at location n - 2 (where n is the number of elements in the array). Then test the type of class of that object using isKindOfClass method and perform the appropriate action.
Rough Example:
-(void)viewDidLoad {
[super viewDidLoad];
NSArray *viewControllers = [[self navigationController] viewControllers];
int parentIndex = [viewControllers count] - 2;
UIViewController *parentVc = [viewControllers objectAtIndex:parentIndex];
if ([parentVc isKindOfClass:ClassA.class]) {
//action
}
else if ([parentVc isKindOfClass:ClassB.class]) {
//different action
}
else ... etc
}

ViewController Hierarchy getting 'lost'

I've got a view hierarchy which is setup (programmatically) as follows:
Window.root = TabBarController-->UINavigationControllers-->UIViewControllers
I presume that's rather standard. Here's my problem:
I'm on Tab A. I want to navigate to Tab B, and call a method on the visibleViewController on Tab B.
// View Changes OK
[AppDelegate.tabBarController setSelectedIndex:tabB];
// nav = 0x387ABF i.e. Valid Address
UINavigationController *nav = (UINavigationController*)[AppDelegate.tabBarController selectedViewController];
// The problem:
nav.viewControllers; // this is nil
nav.topViewController; // as is this
nav.visibleViewContorller; // this too.
Even if I put the calls to nav.viewControllers in a separate method which is called from the Main Thread, I still get 0x0/nil.
What am I doing wrong?
A follow-up question is:
How can I pass information from one ViewController to another when changing tabs? (If I can't call methods on VC's from tabA to tabB)
I have a feeling it is related to my question here.
You should store the information in a common place, either a singleton or as you are a beginner just make a class and pass it down.
sharedDataObject = [[MySharedDataObject alloc] init];
firstViewController.myDataObject = sharedDataObject;
secondViewController.myDataObject = sharedDataObject;

Pass Data Between Two UIViewControllers

I need to pass data of UILabel from ViewB to ViewA. My ViewA has a UILabel with some number. This number can be changed in ViewB which I open as a new UIViewController as below:
viewB = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
ViewB also has a UILabel to hold the same value. I tried to pass this value from ViewB to ViewA by assigning UILabel's like so:
viewB.countdownLabel = self.countdownLabel;
That didn't work. Thanks for suggestions...
i think what you want is:
viewB.countdownLabel.text = self.countdownLabel.text
Make sure viewB.countdownLabel is a retain property and it should work.
By saying "viewB.countdownLabel = self.countdownLabel;" you are simply making viewB's countdownLabel a reference to the original label, you're not copying their values. You need to do the following...
[viewB.countdownLabel setText:self.countdownLabel];
I would suggest that you use AppDelegate to pass the value across to any viewController (and read the documentation here).
GeneralAppDelegate*appDelegate=[[UIApplication sharedApplicaton] delegate];
myLocalProperty=appDelegate.someDataModelProperty;
or just use
viewB.countdownLabel.text = self.countdownLabel.text;
in your code.
KVO also can be used.
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA

Passing Image through UINavigationController

I have an image in my RootViewController (which is selected from a UIImagePickerController), which I need to pass to a new view through a navigation controller. I have the following code that I use to pass strings to the next view:
//Get strings
NSString *text1 = line1.text;
NSString *text2 = line2.text;
NSString *text3 = line3.text;
NSString *text4 = line4.text;
//Create an GeneratedViewController and initialise it with given data
GeneratedViewController *gController = [[GeneratedViewController alloc] initWithNibName:#"GeneratedViewController" bundle:[NSBundle mainBundle]];
gController.text1 = text1;
gController.text2 = text2;
gController.text3 = text3;
gController.text4 = text4;
[self.navigationController pushViewController:gController animated:YES];
[gController release];
gController = nil;
How might I pass an image to the GeneratedViewController?
Thanks,
Jack
The easiest solution would be to create a property of type UIImage on GeneratedViewController.
Then after creating and initializing the GeneratedViewController but before pushing it onto the navigationController you will need to set the image property on the gController to the selected image.
A property on the controller, just like the text is set
In a method, or the initializer
through a notification (NSNotificationCenter). This is a bit more advanced.
Through delegation, where the first controller is a datasource delegate on the Generated Controller. This allows the second controller to get what it needs, whenever it wants.
Which method to use depends on how the controllers are created, when the image can change, and how many different pieces of data the second controller needs - one or two bits, properties work fine. More than that, I tend to use delegation.

updating value of modal view variable

I'm trying to make a modal view which displays the champion of my app.
there's a NSMutableString variable called champ in modal view,
which is supposed to be updated by returnChamp function in main view.
the champ string is correctly set in main view,
but in modal view, the champ value appears as (null).
In fact, it seems it doesn't even go into the returnChamp function.
so apparently something wrong with my calling or implementing returnChamp,
but I have another function that does the similar, and that works fine.
could anyone please help me?
-(void) mainView{
.....
champ = [[currentPlayers objectAtIndex:playerIndex] retain];
NSLog(#"%#",champ);
modalWinner = [[winner alloc] init];
modalWinner.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:modalWinner animated:YES];
}
- (NSMutableString *) returnChamp{
NSLog(#"returnChamp");
return champ;
}
//in modalWinner
-(void) modalView{
..............
champName = [[NSMutableString alloc] init];
NSLog(#"%#", [(MainViewController *)self.parentViewController returnChamp]);
champName = [(MainViewController *)self.parentViewController returnChamp];
UIImage *champImage = [UIImage imageNamed:champName];
}
self.parentViewController is probably not actually a reference to your object. For some reason, it seems that the framework always insists on setting a UINavigationController as self.parentViewController - even for modals, and to the extent that it will create one if there isn't already one. This is probably going unnoticed because you're casting it to your MainViewController type.
You'll need to find a different way of making your original object available to be communicated with, or perhaps pass the appropriate value to the newly-instantiated controller before you present it.
For example, if you add a champName property to the modal class, you can do:
modalWinner = [[ModalWinnerViewController alloc] init];
modalWinner.champName = myValue; /* Set value before presenting controller */
[self presentModalViewController:modalWinner animated:YES];
There will probably be some code needed to update the UI with this value. The viewWillAppear method of the modal view controller is a good place for this as it is called by the framework immediately before the view is presented.
Note that this property-based approach could be used to keep a reference to your intended parent object, as well. And see here for a different approach to solving a similar problem.