I have two controllers A & B
In B there are one label and one string
In A i have write the below code
B *ObjB =[[B alloc]initWithNibName:#"B" bundle:nil];
ObjB.Mylabel.text=[NSString stringWithString:#"Add New name"];
ObjB.MyString=[NSString stringWithString:#"new string name"];
[self.navigationController pushViewController:ObjB animated:YES];
[ObjB release];
I am only getting the ObjB.MyString value in B , not getting the label text.Can any one help.Thanks in advance.
Well assuming that MyLabel is a UILabel (sidenote: avoid capitalized names for ivars - in Objc capitalized names are used [by convention] for Classes), the reason that the value is not set is because the view hierarchy of your B controller has not yet been loaded (ie your label is nil at this point). So you got three options:
Force the view hierarchy to load & then set your label:
[ObjB loadView]; // Note: Apple says that you never should call this directly (just to illustrate my point)!!
Let the system load the hierarchy for you by requesting the view first:
id view = ObjB.view; // This is a bit of a 'hack' actually
Just add another property in your B controller, set that and on viewDidLoad set your label's text (This is the best option in my opinion)
The best way to pass data between two view controllers is to declare a variable in controller B, to hold the labels text.
In viewController B's header file
NSString *labelText;
//Declare its property and synthesize in .m
In controller A, before navigating to controller B, initialize this variable to the text you want, i.e. in this case "Add New Name".
B *ObjB =[[B alloc]initWithNibName:#"B" bundle:nil];
ObjB.labelText = [NSString stringWithString:#"Add New name"];
ObjB.MyString = [NSString stringWithString:#"new string name"];
[self.navigationController pushViewController:ObjB animated:YES];
Next in the viewDidLoad of controller B, assign the label's text to the variable which contains the string.
ViewDidLoad of B
MyLabel.Text = labelText;
//Assuming you have mapped MyLabel to the IB.
Also i use ARC for all my projects, so I dont use the release command.
This solved my problem
B *ObjB =[[B alloc]initWithNibName:#"B" bundle:nil];
[self.navigationController pushViewController:ObjB animated:YES];
ObjB.Mylabel.text=[NSString stringWithString:#"Add New name"];
ObjB.MyString=[NSString stringWithString:#"new string name"];
[ObjB release];
Thanks for your immediate response
Related
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.
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.
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.
I've got a problem that I think is probably straight forward but I can't seem to wrap my head around it.
I've got a tableview that loads from an array of NSDictionaries. Each Dictionary has a title (shown in the row) and an associated nssstring representing a viewcontroller that should be pushed onto the stack when the row is selected. In other words, selecting row "A" needs to initialize an instance of "aViewController" and push it on the stack, selecting row "B" needs to initialize an instance of "bViewController" and push it on the stack, etc.
I originally just hardcoded all possible values into didSelectRow. But I'd really like to be able to dynamically generate the viewController dynamically. I found a few C++ examples of similar problems that led me to the code below. But I can't seem to get it right and am not sure I'm on the right track for an objective-c solution. Anyone have any thoughts?
Here's the didSelectRow code that's not working:
Class cls = [selectedRow valueForKey:#"viewController"];
if (cls!= nil)
{
id myNewController = [[cls alloc] init];
}
[[self navigationController] pushViewController:myNewController animated:YES];
[myController release];
Are you storing the actual Class or the class name (as an NSString) in the dictionary?
If the value you are storing in the dictionary is an NSString I don't think you can just assign Class cls = someNSString;
You can, however, do:
NSString *controllerClassName = [selectedRow valueForKey:#"viewController"];
if (controllerClassName != nil) {
id myNewController = [[NSClassFromString(controllerClassName) alloc] init];
[[self navigationController] pushViewController:myNewController animated:YES];
[myNewController release];
}
OR
Just store the Class in the dictionary instead of the NSString representation:
I have come across a strange behavior...
In class A, at the viewDidLoad method I do:
b = [[B alloc] initWithNibName:#"B" bundle:nil]; //init the B class (declared as B* b)
[b setText:#"ABCDDEEE"]; //change the text of a UITextView in b
note that b's view is not shown until a button is pressed. However, when I press it and go to b's view, the text of the UITextView is still the "lorem ipsun" text
Once b's view is shown once, I can change the text.
Anyone know this issue and how to solve it??
That is expected behaviour. initWithNibNamedoes not guarantee complete initialization before viewDidLoad is called.
Create an NSString #property in B. Set that property when you load b--not the .text property of a UITextView, but an NSString data object in the view controller. Then in B's -(void)viewDidLoad, set the UITextView's text property with the string you set.
NIB elements don't necessarily exist when the parent view controller first instantiates a new view controller, but you can talk to data fields and then load that data into the view hierarchy members in -(void)viewDidLoad.