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
Related
I have a program with Two windows (Both are controlled from the same Class File) and a Global Variable named PersonName1, Window A and Window B. On Window A there are 2 buttons, One which:
-(IBAction)setPersonName:(id)sender
{
PersonName1 = #"Tom";
}
And the other which changes from Window A to Window B
On Window B there is a button which does:
- (IBAction)loadNames:(id)sender
{
NSLog(#"%#",PersonName1);
}
The problem is whenever the screen changes, and when I click the button on Window B, the NSlog returns (null) instead of "Tom". What is causing this?
More information from comment:
PersonName1 is declared in the main ViewController.h file as so:
NSString* PersonName1;
and a property in that file aswell.
#property (nonatomic, retain) NSString *PersonName1;
This is then synthesised in the ViewController.m file. Both the IBActions listed in the question are also both in the ViewController.m file.
i think you did not pass value to one view controller into another view controller.
ex:
first view controller
have global value as NSString *nameString.
like below
#property (nonatomic, strong) NSString *PersonName1;
and
second view controller
it have global string as NSString *nameString
like below
#property (nonatomic, strong) NSString *PersonName1;
when you want pass value to one view controller into another mean.do like below
SecoundViewController *SVC = [[SecoundViewController alloc]initWithNibName:#"nibName" bundle:nil];
SVC.PersonName1 = self.PersonName1;
[self.navigationController pushViewController:SVC animated:YES];
Seems to me like you have to click first button on the first window to allocate value to PersonName1. If you didnt click first button but clicked second button instead then it will return null because declaration on PersonName1 will only happen if you click first button.
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.
i've been doing a thing here using objective-c, but i'm a beginner in this language, and that's what i did:
there is a class, named "firstviewclass", that is in the control of my first view, in this view there is a textfield that the user puts a number. the textfield is in the firstviewclass.h named "setNumber". There is another class, named "secondviewclass" that is in control of the second view, in this view there is a label that is in the secondviewclass.h, and i want that this label recive the value that the user put in the textfield from the first view, but when i test it on the iOS simulator any number that i put in the textfield it appears in the label as 0... I really don't know what to do!
My codes:
firstviewclass.h:
#import <UIKit/UIKit.h>
#interface firstviewclass : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *setNumber;
- (IBAction)gotonextview:(id)sender;
#end
secondviewclass.h:
#import <UIKit/UIKit.h>
#import "firstviewclass.h"
#interface secondviewclass : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *labelthatrecivesthetextfieldvalue;
#end
secondviewclass.m:
#import "secondviewclass.h"
#import "firstviewclass.h"
#implementation secondviewclass
#synthesize labelthatrecivesthetextfieldvalue;
-(void)viewDidLoad{
[super viewDidLoad];
firstviewclass *object = [[firstviewclass alloc] init];
NSString *string = [[NSString alloc] initWithFormat:#"%i", [object.setNumber.text intValue]];
labelthatrecivesthetextfieldvalue.text = string;
}
#end
First of all, I would strongly recommend not naming a property or instance variable setSomething. It will cause headaches for anyone reading your code because it will always look like you're trying to call a setter. Also, please do capitalize your class names.
Your actual problem is that in viewDidLoad you're creating an instance of firstviewclass, and then trying to get the value from setNumber. That is before the user had any chance to enter anything.
Also, the setNumber outlet in firstviewclass will probably be going nowhere anyway, since you're instantiating that class yourself, instead of loading the NIB.
Edit (ah, Storyboard, d'oh):
For Storyboard, you need to pass the setNumber text field's value to the second view.
First of all, remove the firstviewclass *object = [[firstviewclass alloc] init]; line.
Then, in your first view controller's prepareForSegue method, you can pass the value of the setNumber text field to a property in your your second view controller, and use it from there (e.g. in configureView).
I recommend working through Apple's Storyboard tutorial, it shows exactly what you need to do, step by step. The step you're having issues with right now, passing data to your next view controller, is here.
How are you initiating the setting of the label? From viewDidLoad? If so, then 0 would be correct because you have not set object.setNumber.text to anything. Also, you aren't carrying over the data from your first viewController. You need to let the second viewController know what the number is. Try setting this value in your NSUserDefaults, then in your second viewController, load that value from your defaults.
in the viewDidLoad of secondviewclass, you are creating a new instance of firstviewclass, and then accessing the property of the label. Since you haven't set that to be anything, it will always return zero.
Can you post the implementation of the gotonextview method?
EDIT:
I think you need to be setting the label property from the first view controller. so in your gotonextview method, add this line:
secondviewclass.labelthatrecivesthetextfieldvalue.text = self.setNumber.text;
I admit I'm a little lost in your naming scheme but that might work.
I am building a utility-based application, the data is stored in the MainViewController, and now I know how to pass data to the FlipsideViewController (many regards to this thread BTW, Sending data from Mainview to Flipside?). But I am getting the data onto an subview (subclass of UIView) that I have added to the flipside view. How can I pass data to this subview? I saw there is already a delegate and protocol set up in the FlipsideViewController.h, I am really new to the delegate sort of things. Any help would be greatly appreciated!
Updates:
On the main view, I have a couple of text fields for users to input to create an object. All the objects are stored in an array. Namely, my data is created and stored in the MainViewController. Now on the flip side, I have a custom UIView subclass which allows me to do my own drawing based on the data in that array. What I need to do here is pass the data that stored in MainViewController to this subview. Here is my relevant code:
In the MainViewController.m
- (IBAction)showInfo:(id)sender {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.receiver = data;//this is what I've done.
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
In the FlipsideViewController.h
#protocol FlipsideViewControllerDelegate;
#interface FlipsideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
DataModel *receiver; //create a property to receive the data transferred from main view
}
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
#property (nonatomic, retain) DataModel *receiver;
- (IBAction)done:(id)sender;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
In the above code, "data" is an DataModel object declared in the MainViewController.h file.
And I want to do my custom drawing in drawing class (subclass of UIView), how can I pass data from the FlipsideViewControllerto this subview? Do I need to make use of delegate declared in the FlipsideViewController.h file? Thanks in advance!
I have had a quick look at the template and think you are getting confused with what the delegate is being used for.
The delegate in this template is not transferring data. When you have clicked the done button it calls back to MainViewController and asks it to call the dismissModalViewControllerAnimated method so that it can remove the view controller. This seems a bit superflous as the documentation states
If you call this method on the modal view controller itself, however, the modal view controller automatically forwards the message to its parent view controller.
Therefore you don't really need to call the parent to do this.
In Interface builder you can see that the FlipsideView.xib has it's File's Owner set to FlipsideViewController.xib.
Now if you right click the File's Owner you will see that view is connected to View this basically means that view is the name of the property in FlipsideViewController and View is the element in Interface Builder.
Therefore we can access elements in the xib file from FlipsideViewController using outlets.
To say draw a label you will need to do a couple of things
First add a property in the .h and synthesize it in the .m like
// FlipsideViewController.h
#interface FlipsideViewController : UIViewController
#property (nonatomic, retain) IBOutlet UILabel *testLabel; // <----- Added this
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
#end
// FlipsideViewController.m
#implementation FlipsideViewController
#synthesize delegate = _delegate;
#synthesize testLabel = _testLabel; // <----- Added this
// More methods
- (void)dealloc
{
[_testLabel release]; // Always do you memory management
[super dealloc];
}
Then back in Interface Builder
Add a UILabel element to your view
ctrl + drag from File's Owner to the UILabel you added
Select the label in my example it is testLabel
Now these are hooked up correctly. The place where you want to be setting the value of the label is in viewDidLoad: which you can now do like this
- (void)viewDidLoad
{
[super viewDidLoad];
self.testLabel.text = #"It Works"; // You would use the data passed in from `MainViewController`
}
I find the easiest way to pass data from one view to another is by directly setting the data in the next view from the original view.
For example;
In your FlipsideViewController.h, declare a 'container' for the data you want to pass. It must be the same class on both sides to work properly, ie. NSArray to NSArray, NSMutableDictionary to NSMutableDictionary.
NSMutableArray *newData;
...
#property (nonatomic, retain) NSMutableArray *newData; // This allows you to access this object from outside this class.
and in FlipsideViewController.m
#synthesize newData;
...
[newData release];
Now we need to pass the data, so to speak. Let's say the data we want to 'send' is stored in a NSMutableArray called 'results'.
In our MainViewController.m, when we are instantiating our next view controller (in this case FlipsideViewController) we can directly reference the newData mutable array after we initalize the nib.
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.newData = results;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
Make sure you are importing your FlipsideViewController in your MainViewController.h file.
If the property is declared in your .h file, you can pretty much reference the contents of the object from anywhere within the view stack!
Hope that helps :D
I would like to get at
- (void)applicationWillTerminate:(UIApplication *)application
a variable from a view controller class.
I have build an tabbar application and only added the tabbar controller to the appdelegate.
[window addSubview:tabBarController.view];
How can i get an variable from the TestViewController:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface TestViewController : UIViewController {
IBOutlet UILabel *testLabel;
NSString *currentString; //Value that i want to save at applicationWillTerminate
}
#property (nonatomic, retain) UILabel* testLabel;
#property (nonatomic, retain) NSString* currentString;
#end
It's somewhat incidental that TestViewController hasn't been dealloc'd by the time you reach applicationWillTerminate - it might make sense to store that value a level higher in your application. That approach would be to always store currentString in the UIApplicationDelegate so that you don't have to fetch it later:
#implementation TestViewController
- (void)setCurrentString:(NSString *)currentString {
((MyAppDelegate *)[[UIApplication sharedApplication] delegate]).currentString = currentString;
}
#end
Expanding on dbarker's answer, it sounds like what you really need is to save the currentString value in your data model. The proper place to do that is in the viewController itself.
If your data model is just that one string, you can create a property in the app delegate to hold it. Then the viewController writes to the app delegate property whenever the value of currentString changes in a view and/or its value when the view closes.
This way, the data (which is the entire point of the app anyway) is always in place when the app closes regardless of how many views you open.
It is the proper role of controllers to move information from the interface to the data model. Strictly speaking, the viewController shouldn't store any data at all beyond that needed by the interface itself. That should be a property of the data model which the viewControllers set by sending a message to the data model object with the values taken from the interface.
In this case, you would not have a currentString property in your view controllers. Instead they would have a property that is just a reference to the data model's currentString property. The view controllers would continuously update that property but would store nothing themselves.
The advantage of this design is obvious. If you need the value anywhere in your app, you have one location and one call to get it. No single part of the app needs to even know of the existence of any other part of the app save for the data model.
Not 100% sure what you are asking for but here is a guess:
UITabBarController's have a property called viewControllers which return all view controllers associated with the tabbar.
Assuming that the TestViewController was the first tab you could get to it by:
- (void)applicationWillTerminate:(UIApplication *)application {
TestViewController* test_view_controller = [tabBarController.viewControllers objectAtIndex:0] ;
NSString* value = test_view_controller.currentString ;
}
Note this would break if you decided to later move the TestViewController to a different position in the tabbar.
-- Edit --
Check all controllers and get the string from the controller that is of type TestViewController.
NSString* value = nil ;
for ( id unknownController in tabBarController.viewControllers ) {
if ( [unknownController isKindOfClass:[TestViewController class]] ) {
value = ((TestViewController*)unknownController).currentString ;
}
}
// value should be the value of the string.