NSString property from textview disappear - ios

I have a view that through a prepareSeque method should pass whatever is written in a textView to the next view.
Before I had textField and textfield.text in the seque method worked fine. But I can not get it to work with a textView.
I have a NSString property in the .h file: #property (weak, nonatomic) NSString *textString;
I syntesize it in the .m file: #synthesize textString =_textString;
In my textViewDidEndEditing i can see (through debug) that the text in the text View is picked up and that the textString is set.
(void)textViewDidEndEditing:(UITextView *)textView {
NSString *theText = textView.text;
self.textString =theText;
}
However, when I then want to retrieve the textString in my Seque method it does not contain any text:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"go"]) {
ISecondViewController *vc = [segue destinationViewController];
vc.funnyString = self.textString;
}
If i enter: self.textString =#"Hi Hi"; in the Seque method funnyString will be passed with Hi Hi so that part works fine.
Have I just totally misunderstood the "get and set" of NSString in this case?

Your problem here is that you have been using a weak property for textString so it will be nil when the scope of your property get out of your textViewDidEndEditing method.
Why? because the principle of weak reference is that it will be set to nil as soon as the object you are referring to doesn't exist anymore. This will be the case for the "theText" object which won't exist at the end of your method. Use a strong property instead.

Related

prepareForSegue not setting UILabel

I have a prepareForSegue method setup in that sends everything I want to the destinationViewController except the value for a UILabel on the destinationVC. I threw a NSLog statement in to see what value it prints and it prints what I want.
It doesn't crash, but it doesn't set. I know I'm missing something very basic here, but it's not jumping out at me.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UIButton *)sender {
if ([[segue identifier] isEqualToString:#"directionsSegue"]) {
// Set destination view controller
DirectionsViewController *destinationVC = segue.destinationViewController;
// Pick out the "thing" you want to send to destinationVC
CGPoint point = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];
// Set the "thing" on the destinationVC
PointOfInterest *poi = [self.fetchedResultsController objectAtIndexPath:indexPath];
destinationVC.destinationLabel.text = poi.name;
NSLog(#"destinationVC.destinationLabel.text = %#", poi.name);
destinationVC.destinationLatitude = poi.latitude;
destinationVC.destinationLongitude = poi.longitude;
}
}
My property declared in the header of my destinationVC:
#property (strong, nonatomic) IBOutlet UILabel *destinationLabel;
Solution from answers below:
Mystery solved! Here's what I did:
on my destinationVC, I added this to my header:
#property (nonatomic, strong) NSString *destinationName;
I put this back in the implementation:
#property (strong, nonatomic) IBOutlet UILabel *destinationLabel;
In destinationVC, I added this to my viewDidLoad:
self.destinationLabel.text = self.destinationName;
Your label will be nil in prepareForSegue because it won't be instantiate at this time. In fact, IBOutlet are initialised yet once your view is loaded. That's why it's not working.
The best way to solve your issue is to create another property in your DirectionsViewController where will be stored your text. This one is available directly after your controller initialisation, and then you can set your label directly wherever in your controller.
IBOutlet objects are not initialized until the view controller's view loads. That happens after the segue. Create a custom property and update that during prepare and then copy it to your label during viewDidLoad.

Save Inputed textField data into a csv file

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.

Sending data from a UIlabel from one view controller to another

I have two view controllers
DetailViewController
BlogViewController
I have a 'push' set-up on the storyboard with the identifier 'ShowBlog'
i need to send the title of the blog from the UILabel below on the DetailViewController:
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
to a UILabel on the BlogViewController called BlogTitleLabel:
#property (strong, nonatomic) IBOutlet UILabel *BlogTitleLabel;
i know i need to use:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowBlog"]) {
// Im struggling with the code
}
}
But im struggling with the code to go in it
Use NSUserDefaults the code goes something like this:
Store the title:
[[NSUserDefaults standardUserDefaults] setObject:label.title forKey:#"nameForStoredVariableHere"];
[[NSUserDefaults standardUserDefaults] synchronize];
Retrieve the stored title:
NSString *storedTitle = [[NSUserDefaults standardUserDefaults] objectForKey:#"nameForStoredVariableHere"];
After that you're free to use the title as you please
prepareForSegue is called before destination VC's viewDidLoad so don't try to access any view object of destination view controller in prepareForSegue. Its better you create a string property in destination and set that in prepareForSegue method. In destination viewController's viewDidLoad set it to label.
You should not try to send data from label to label. Labels are view objects. They display information and collect input from the user. They do not store information.
Also, you should never, ever try to manipulate another view controller's views directly. That violates the other view controller's encapsulation.
Both view controllers should have NSString properties for this. Let's call it blogTitle on both VCs.
Your DetailViewController should set it's blogTitle somewhere during it's setup, and then in viewWillAppear:animated, display that value to it's titleLabel outlet:
- (void) viewWillAppear: animated;
{
[super viewWillAppear: animated];
self.titleLabel.text = self.blogTitle;
//your other code here
}
Then, in your prepareForSegue:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowBlog"])
{
BlogViewController *theBlogController = [segue destinationViewController];
theBlogController.blogTitle = self.blogTitle; //Pass the blog title to the other VC
}
}
And then in the BlogViewController's viewWillAppear, copy the blogTitle to it's title label:
- (void) viewWillAppear: animated;
{
[super viewWillAppear: animated];
self.titleLabel.text = self.blogTitle;
//your other code here
}
Note that Cocoa/iOS programming has strong naming conventions that you should follow. Only filenames and class names should start with a capital letter. Method names, instance variable names, and property names should start with a lower-case letter. So your TitleLabel should be titleLabel, and BlogTitleLabel should be blogTitleLabel.

Transferring String from UIViewController using Segue

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;

Accessing strings through segues on ios 5

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!

Resources