How to pass a value to parent view controller? [duplicate] - iphone

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
dismissModalViewController AND pass data back
I'm new to ios development and stuck on this problem:
I'm using storyboarding and have a navigation controller, vcA, with a TableView in it which shows some data from a MutableArray (which is initialized in viewdidload of the same class). After selecting any cell, a second view controller, vcB, is shown with a TextField in it and a button called "Add to list".
What I want is that when I enter some text in the TextField and press the "Add to list" button the text should be added to the array of previous view (which gets shown in the TableView) and when i tap the "Back" button on vcB's navigation bar, vcA should show the updated TableView with the new entry in it (on the top of list). Basically I want to add the text from vcB's TextField to the array of vcA and show the new array after clicking the BACK button.
I have searched a lot about this issue and seem to find that delegate and protocols is the way to achieve the desired result but I'm having trouble understanding delegation.

I have the second view controller presenting itself as modal in this example:
In the second view controllers h file:
#protocol SecondViewControllerDelegate <NSObject>
- (void)addItemViewController:(id)controller didFinishEnteringItem:(NSString *)item;
#end
#interface SecondPageViewController : UIViewController <UITextViewDelegate>
{
NSString *previouslyTypedInformation;
}
#property (weak, nonatomic) IBOutlet UITextView *textView;
#property (nonatomic) NSString *previouslyTypedInformation;
#property (nonatomic, weak) id <SecondViewControllerDelegate> delegate;
In the second view controllers m file make sure to synthesize properties and add then add this:
- (IBAction)done:(id)sender
{
NSString *itemToPassBack = self.textView.text;
NSLog(#"returning: %#",itemToPassBack);
[self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
//dismiss modal view controller here
}
Then in the first view controllers h file set it as delegate:
#interface FirstPageViewController: UIViewController <SecondViewControllerDelegate>
#property (nonatomic) NSString *returnedItem;
Then in the first view controller's m file synthesize and add the method:
- (void)addItemViewController:(SecondPageViewController *)controller didFinishEnteringItem: (NSString *)item
{
//using delegate method, get data back from second page view controller and set it to property declared in here
NSLog(#"This was returned from secondPageViewController: %#",item);
self.returnedItem=item;
//add item to array here and call reload
}
Now you have the text of what was returned! You can add the string to your array in the first view controller's viewDidLoad and call
[self.tableView reloadData];
and it should work.

Related

Change UInavigationbar title back page

i have two screen. i want click button first screen after navigation bar change in second screen.
i using storyboards
first screen code
-(IBAction) ChangeSecondPageTitle: (id) sender {
SecondViewController *second=[[self storyboard] instantiateViewControllerWithIdentifier:#"second"];
second.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;
second.detailTitle.topItem.title=#"example";
[self presentModalViewController:second animated:YES];
}
second screen.h
#property (weak, nonatomic) IBOutlet UINavigationBar *detailTitle;
I guessing you are trying to set title for your second screen navigation bar.
Use a navigation controller to present your second screen.
In SecondDetailViewController instance, maintain a NSString property.
#property (strong, nonatomic) NSString *navBarTitle;
In viewDidLoad, just set the title.
[self setTitle:navBarTitle];
Actually the reason your code is not working is you set the property to your nav bar and then your viewDidLoad get called. In viewDidLoad it loads the nib file and return new allocated navBar. So to Solve this take a global string set it from first view and then in second in viewDidLoad set your navbar's title. Follow
Adithya's answer for that.
In second screen declare a property
#property (strong, nonatomic) NSString *newTitle;
and in viewDidLoad
self.title = _newTitle;
and in your first screen
...
second.newTitle = #"NEW_TITLE";

How can I show the selected value from uipickerview to anotherview

Can anyone tell me how can I show the value from one a UIPickerView in another view? I am storing a value in a label but I have to show this value in a button in another view controller.
Typically you would store the value data in your model when the user closes the second view. and the first view would read the value from the model when it re-appears (or use notifications). Your model data could be a plist, or nsuserdefaults or core-data etc.
Alternatively you could create a reference to the first viewController when you create your second viewController and assign this as a property on the second viewController. Then the second viewController in effect has a "path" to the first viewController:
The first viewController would have a property such as:
NSString *myStr; // in the header
#property (nonatomic, retain) NSString *myStr; // in the header file
#synthesize myStr; // in the implementation file
The second viewController would have a property such as:
firstViewController *firstVC; // in the header
#property (nonatomic, retain) firstViewController *firstVC; // in the header file
#synthesize firstVC; // in the implementation file
When you create the second viewController you would do something like:
secondViewController.firstVC = self; // in the implementation file
Then when you want to update myStr in the first ViewController (from the second viewController) you would do something like:
firstVC = #" my new value "; // in the implementation file

How to pass variables between 2 view conrollers

I have 2 view controllers now, And it both got tableviews.
When I choose a row in the second tableview (Using didSelectRowAtIndexPath),
and I want to pass the Information I got in the second View to the first View,
I tried to use delegate&protocol, but don't know why, It didn't work.
And I tried to use class method inside the first class, when I got variable in sencond View,
Call the class method inside the first class. The variable successfully pass to first View,
but when I want to set the Lable's text, it still failed..
Can somebody teach me how to do? thanks!
My protocol&delegate.
This is the second view.
#protocol CategoriesViewControllerDelegate;
#interface CategoriesViewController : UIViewController {
TableViewNewAppDelegate *appDelegate;
id <CategoriesViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <CategoriesViewControllerDelegate> delegate;
#end
#protocol CategoriesViewControllerDelegate <NSObject>
-(void)backstring:(NSString *)String;
#end
In the .m file , synthesize it
#implementation CategoriesViewController
#synthesize delegate;
didSelectRowAtindexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
CategoryData *CateObj = [appDelegate.CateArray objectAtIndex:indexPath.row];
NSString *Strings = [NSString stringWithString:CateObj.CateTitle];
[delegate backstring:Strings];
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
In the first view controller .h file.
#import "CategoriesViewController.h"
#interface DataController : UIViewController <CategoriesViewControllerDelegate>{
.m file
-(void)backstring:(NSString *)String {
NSLog(#"%#",String);
jCateField.text = String;
}
This is how I do my protocol+delegate. Are there something wrong?
btw, I created a Class method in the first view controller, and use the Class method in the sencond view controller, it succesfully pass variable to first view controller.
But the problem is, I can't set my Label's text inside my Class method, even calling Instance method to set text. Is there any way to solve this problem?
The code you provided seems to be correct. In your case you must set :
#property (nonatomic, assign) id <CategoriesViewControllerDelegate> delegate;
correctly to point to the first view controller which conforms to the protocol you defined :
#import "CategoriesViewController.h"
#interface DataController : UIViewController <CategoriesViewControllerDelegate>{
So it seems that you pushed a CategoriesViewController onto a first DataController, you probably missed to do so just before.
// self is the first view controller
// [myCategoriesViewController setDelegate:self]; old fashion
myCategoriesViewController.delegate = self;
[self presentModalViewController:myCategoriesViewController animated:YES];
This can probably solve your issue. Hope this helps.
Also consider let the first controller dismiss the second.
Here is a link to Apple's documentation.
You could just pass the information straight on to your second view controller;
SecondViewController.h
#interface SecondViewController
{
Information *info;
}
#property (nonatomic, retain) Information *info;
#end
SecondViewController.m
#implementation SecondViewController
#synthesize info;
...
#end
And in your didSelectRowAtIndexPath method;
SecondViewController *controller = [[SecondViewController alloc] initWithNibNamed:#"SecondViewController" bundle:nil];
[controller setInfo:YOUR_INFO_OBJECT];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
Import second view controller header file in the first view controller implementation file. Import first view controller header file in second view controller header file.
Create the property (text/label/whatever) in the first view controller.
Create the property of first view controller in the second view controller.
Create the second view controller instance, set the first view controller property to what you need, push controller to the navigation controller. In the second view controller change whatever you want in the first view controller. Instance methods allowed. Do not forget to release first view controller.
Delegate pattern works in that way too.
View controllers are objects. Objects can have methods that can be called from other objects, and they can have instance variables. ("Delegate" is just a fancy term for this.)
There's no inherent reason why passing data between your view controllers should be hard or complicated, so long as the caller has the address of the callee. (And whether or not a given VC has an XIB is irrelevant.)
It sounds like your real problem is not knowing what to do with the data once it's been passed to the callee.
Stupid question: Is "jCateField" actually connected to the label you want to change, or is it nil? If you created the label from code (since you don't have an XIB), you will need to have stored the created label's address into "jCateField" during the view creation.
Can you post the code for as to ho you are displaying the contents when you come back to 1 st view controller.As here if the log gives you proper value then the issue is with the connection (if taken through iboutlet) or with addsubview .
Do you get nil in label or no value (label is hidden).

reload tableview from navigation controller

I am new to iPhone development.
I have a navigation controller which loads a tableview. The class identity of the tableview is a tableViewController class.
I want to know how to refresh the table view from the navigation controller.
I know within the tableViewController i can use the
[self.tableView reloadData];
Sorry if i am vague.
Thanks in advance.
after feedback:
Here is the navigation controller
#interface slNavController : UINavigationController{
UIToolbar *toolbar;
slTableViewController *tableVC;
}
#property(nonatomic, retain) slTableViewController *tableVC;
where slTableViewController is the Delegate of the tableView that needs to be refreshed.
and where i needed to refresh the table i used
[tableVC.tableView reloadData];
Here is slTableViewController header
#interface slTableViewController : UITableViewController <UITableViewDelegate,UITableViewDataSource> {
IBOutlet UITableView *slTableView;
NSMutableArray *list;
TryAppDelegate *appDelegate;
//UIToolbar *toolbar;
IBOutlet UITextField *textField;
}
But still not able to refresh the tableview.
There must be some viewController which is the delegate of the tableView. Send reloadData to that controller, e.g.
[viewController.tableView reloadData];
If you know where in the stack the viewController is, you can access it through the navController. For instance, if it happens to be the rootViewController, then you can do
HomesViewController *homesController = [[[self navigationController] viewControllers] objectAtIndex:0];
If it is Navigation based application you want to reload the data of table view, You have to write in view will appear like this
[self.tableView reloadData];
Give your navigationController a pointer to the tableViewController.
In the .h file:
#property(nonatomic, retain) YourTableViewController *tableViewController;
Then when you want to reload data:
[tableViewController.tableView reloadData];

How return a value from view2 to view1 when using navigation bar

I am New to the iPhone Development. How can i carry a string value from view2 to view1 when using navigation bar. I have no problem in carrying string values from view1 to view2 to view3 to....by using pushviewcontroller But when i come back to previous views using Back button of navigation bar, I cannot able to hold string values.
I need your help in solving this issue.
Thanks In Advance
This thing can be done easily if the pass the reference of the current class to the next class and change the values by using this reference.
Like:
The class that is to be pushed.
#interface B:UIViewController{
id delegate;
}
#property (nonatomic,retain) id delegate;
#end
#implementation B
#synthesize delegate;
-(void)methodA{
[delegate setNewString2:#"Madhup"];
}
#end
The class from which you are pushing B:
#interface A:UIViewController{
NSString *newString;
}
#property (nonatomic,retain) NSString *newString;
#end
#implementation A
#synthesize newString
- (void)method2{
B *newBObject = .......;
[newBObject setDelegate:self];
[self.navigationController pushViewCo.......];
}
#end
Hope this helps.
There's more than one way to do this. Here are a few:
You can access all the view controllers in the navigation stack via the navigation controller's viewControllers property: self.navigationController.viewControllers
You can reach the previous view controller (i.e. the one that pushed the current controller onto the navigation stack) via the parentViewController property: self.parentViewController
You can use the delegate pattern, where the previous (parent) view controller would be the current (child) controller's delegate.
You can keep a reference (retain) to the child controller in the parent controller.
In the first 3, the child controller would be responsible for handing the data to the parent controller. In the 4th, the parent would get the data from the child before releasing it.