I am doing the following:
#ViewController1.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Transferring");
guestViewController *controller = [segue destinationViewController];
[controller.label isEqualToString:self.num_value.text];
}
However when the view is loaded, the text does not run through or show up in the label. I have done this in past programs and it has worked on Xcode 4. However, for some reason in Xcode 5 it is not working for me. Is there something else that I need to implement to make this work in Xcode?
Add this to your guestViewController's header file :
#property (nonatomic, strong) NSString *value;
The your prepareForSegue method becomes something like this :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Transferring");
guestViewController *controller = [segue destinationViewController];
[controller setValue : self.num_value.txt];
}
isEqualToString is for comparison! Not to be used for assigning values.
Then in your viewDidLoad method, add this :
[textLabel setText : value];
[controller.string isEqualToString:self.num_value.text];
isEquelToString only check is controler.string is the same or not as self.num.value.text.
- (BOOL)isEqualToString:(NSString *)aString
Returns a Boolean value that indicates whether a given string is equal
to the receiver using a literal Unicode-based comparison.
Read the apple documentation
your can pass your string to the another controller like this:
In guestViewController's h file :
#property (nonatomic, strong) NSString *theStringWhatYouWantToGet;
and in prepareForSegue:
controller.theStringWhatYouWantToGet = self.num_value.text;
Related
I want to save the inputed data from 3 textfields. I think I will store them in a CSV-file. The problem is that I want to display it in another viewController. or can I do it in a single view controller?
the user will type in their infon in the view controller1, then there is a called "Den här texten kommer att sparas" will show a NSString with all the information that is typed in, and that is what I want to store and show in some kind of list/table in the second view controller.
My question is: How can I access the NSString from the left viewController? Or is there an easier way to solve this problem, e.g. in a single view controller?
If you are changing the ViewController using a storyboard segue, the easiest way would be to pass it using the -prepareForSeguemethod. You have to set the segue identifier in the storyboard, select the segue and set your identifier text in the attributes inspector.
You will need to create propertys in your destination ViewController for the objects you want to pass.
Add this to your destinationViewController.h
#property (nonatomic, strong) NSString *tf1String;
#property (nonatomic, strong) NSString *tf2String;
#property (nonatomic, strong) NSString *tf3String;
Then import the destinationViewController.h file in your firstViewController.hfile.
#import "destinationViewController.h"
Then add the following method to your firstViewController.mfile
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_IDENTIFIER"]) {
DestinationViewController *destinationVC = [segue destinationViewController];
destinationVC.tf1String = [yourTextField1 text];
destinationVC.tf2String = [yourTextField2 text];
destinationVC.tf3String = [yourTextField3 text];
}
}
You may have to change some variables names in order to get this code working.
I'm very new to iOS development and I know there have been questions like this asked, but I can't seem to pull out of those examples what I think I need.
I'm trying to teach this to myself by coding a very simple mortgage calculator. I have two views, MortgageCalculatorViewController where the user enters the loan value, term and interest; and the ResultsViewController where this information is redisplayed, with the monthly payment, in labels. My current issue is I can't seem to figure out how to relay the calculated monthly payment value to the ResultsViewController.
I named the segue showResultsSegue.
In MortgageCalculatorViewController:
#import "MortgageCalculatorViewController.h"
#import "ResultsViewController.h"
#interface MortgageCalculatorViewController ()
#end
#implementation MortgageCalculatorViewController
NSString *paymentText;
-(IBAction)calculateMonthlyPayment
{
float rate = (self.interestRate.text.floatValue / 12) / 100;
long term = self.termInYears.text.integerValue;
float principle = self.loanAmount.text.floatValue;
float termedRate = pow((1 + rate), term);
float payment;
payment = (principle * rate * termedRate) / (termedRate - 1);
paymentText = [NSString stringWithFormat:#"%f", payment];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"showResultsSegue"]){
ResultsViewController *controller = (ResultsViewController *)segue.destinationViewController;
controller.paymentLabel.text = paymentText;
}
}
#end
And in ResultsViewController:
#interface ResultsViewController : UIViewController
#property (nonatomic) IBOutlet UILabel *loanAmountLabel;
#property (nonatomic) IBOutlet UILabel *termInYearsLabel;
#property (nonatomic) IBOutlet UILabel *interestRateLabel;
#property (nonatomic) IBOutlet UILabel *paymentLabel;
-(IBAction)close;
#end
I've guided this approach on the information I found in Passing Data between View Controllers, but I'm still seeing no change after the segue.
Any help would be appreciated. Thanks.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"showResultsSegue"]){
ResultsViewController *controller = (ResultsViewController *)segue.destinationViewController;
controller.paymentLabel.text = paymentText;
}
}
When preparing for a segue, the view has probably not been loaded, so paymentLabel is nil. Instead, declare a paymentText property on ResultsViewController and assign that value to paymentLabel in viewDidLoad.
New prepareForSegue:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"showResultsSegue"]){
ResultsViewController *controller = (ResultsViewController *)segue.destinationViewController;
controller.paymentText = paymentText;
}
}
Implementation for ResultsViewController:
#interface ResultsViewController : UIViewController
#property(copy, nonatomic) NSString *paymentText;
#end
#implementation ResultsViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.paymentLabel.text = self.paymentText;
}
#end
It's likely that your ResultsViewController has not initialized it's view elements, including the paymentLabel yet. Try explicitly calling view before setting the label text like so:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"showResultsSegue"]){
ResultsViewController *controller = (ResultsViewController *)segue.destinationViewController;
[controller view];
controller.paymentLabel.text = paymentText;
}
}
Calling view will cause the view controller to load it's view elements, hence letting you set the label's text properly.
By far the easiest why to do this without using delegates, singletons or as mentioned above using the prepareForSegue, is using NSUserDefaults.
Save string:
[[NSUserDefaults standardUserDefaults] setObject:paymentText forKey:#"payment"];
[[NSUserDefaults standardUserDefaults]synchronize];
Read string:
NSString *readPaymentString = [[NSUserDefaults standardUserDefaults] stringForKey:#"payment"];
What you basically need to do here is to use the save code I provided in one view and the read code in the second view, simple.
I hope it makes sense.
I'm trying to pass some values from a view to another, but the values are always (null). Here my code.
First:
[self performSegueWithIdentifier:#"Thanks" sender:self];
Then:
-(void)prepareForSegue:(UIStoryboardSegue *)segue
{
ThanksViewController *vc = [segue destinationViewController];
[vc set_event_image_url:[NSString stringWithFormat:#"bla bla bla %#.png", event_id]];
[vc set_event_name:eventTitle];
}
In the receiver I'm initiating the variables.
#property(nonatomic,copy) NSString* _event_name;
#property(nonatomic,copy) NSString* _event_image_url;
AND
#synthesize _event_image_url;
#synthesize _event_name;
The values are now (null). Any Ideas why it fails? The segue is added to the storyboard too.
I would remove the underscores from your property names - it's not the standard way of naming things in objective-c and it's just possible that it could be confusing things (cocoa by default will synthesise you instance variables that begin with an underscore).
#property(nonatomic,copy) NSString* eventName;
#property(nonatomic,copy) NSString* eventImageUrl;
You can also remove your synthesize statements - objective-c will do your synthesizing for you, so they're not necessary.
You would then call [vc setEventTitle:blah];
However, the main issue is that you've implemented prepareForSegue incorrectly! The proper method signature should be:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
Add the sender parameter and you should find it'll be called.
I am using the following to create a reference to a view controller in my code like this:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"detailSegue"]){
NSIndexPath *indexPath=[self.tableView indexPathForSelectedRow];
TRDetailViewController *vc=segue.destinationViewController;
vc.item=self.items[indexPath.row];
[vc setValue:self forKeyPath:#"delegate"];
[vc setValue:indexPath.row forKeyPath:#"itemIndex"];
}
}
and this is declared as in TRDetailViewController
#interface TRDetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *detailLabel;
#property NSString *item;
#property (nonatomic, weak)id delegate;
#property NSInteger itemIndex;
- (IBAction)deleteItem:(id)sender;
#end
but I get the following error
and I'm not sure why. I am trying to pass the location in an index of the cell selected in a UITableView. If a better way, please let me know. Why am I getting this error?
thx
setValue:forKey: is expecting an object for its value argument and you are passing it a primitive (in this case, an integer). You can work around this by amending your method to read as follows:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"detailSegue"]){
NSIndexPath *indexPath=[self.tableView indexPathForSelectedRow];
TRDetailViewController *vc=segue.destinationViewController;
vc.item=self.items[indexPath.row];
[vc setValue:self forKeyPath:#"delegate"];
[vc setValue:[NSNumber numberWithInt:indexPath.row] forKeyPath:#"itemIndex"];
}
}
And then access it like:
[[vc valueForKey:#"itemIndex"] intValue];
setValue:forKeyPath: requires an object (i.e. id) as first argument.
You are instead passing a NSInteger.
You will have to use an object type, which means to turn your itemIndex into a NSNumber.
Then you can store it using
[vc setValue:#(indexPath.row) forKeyPath:#"itemIndex"];
and retrieve it by
NSInteger myIndex = [vc valueForKey:#"itemIndex"].integerValue;
I've got a question concerning my Storyboard. I want to change the value of a string which is in ViewA through a segue. That means that ViewB should do the segue and in preparation for that changing the value of the string in ViewA. My problem is now, that the value of my string stays unchanged.
ViewA.h file:
#interface NewViewController : UITableViewController <MKAnnotation>
{
NSString *longString;
}
#property (weak, nonatomic) NSString *longString;
ViewB.m file:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"transmitCoordsToNew"])
{
NewViewController *controller = (NewViewController *)segue.destinationViewController;
controller.longString = [NSString stringWithFormat:#"%f", segueLong];
}
}
Any idea why the variables stay unchanged or why I can't see any changes on further operating in ViewA?
Thanks in advance,
Phil
I'm not sure where your variable segueLong comes from, but having a weak reference to longString is most likely what's causing the problem. Change that to a strong reference and see if it works then.
If in prepareForSegue your NewViewController *controller is receiving a valid (non nil) value from [NSString stringWithFormat:#"%f", segueLong]; I am about 90% sure that the 'weak' property attribute is responsible for the value turning to nil.
Here's why!
[NSString stringWithFormat:#"%f", segueLong] has a scope limited by the prepareForSegue method, also it has no owner (aka no reference is counted for it). Even if segueLong has an owner and will not be released by arc, the resulting NSString from stringWithFormat does not!
What you need to do is change weak, to strong.
:
#interface NewViewController : UITableViewController <MKAnnotation>
{
__strong NSString *longString;
}
#property (strong, nonatomic) NSString *longString;
This ensures that the string generated by NSString stringWithFormat will belong to your NewViewController!