Why wont my UITextField save? - ios

When my UITextView places a line of text into my first UITextField i cant save the text it holds.
Heres my code, this is to move the information from a textview
-(IBAction)print:(id)sender {
NSLog(#"text = %#",[textView text] );
NSArray *textArray = [[textView text] componentsSeparatedByString:#"\n"];
if (textArray.count > 0) {
NSString *line1 = textArray[0];
[myTextField setText:line1];
if (textArray.count > 1) {
NSString *line2 = textArray[1];
[myTextField1 setText:line2];
}
}
[textView setText:#""];
[textView resignFirstResponder];
}
Heres how i am currently trying to save and load the information.
- (void)viewDidLoad {
[super viewDidLoad];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[myTextField setText:[defaults valueForKey:#"textfield_text"]];
[myTextField setDelegate:self];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *defaultsKeyForTextField;
if ([textField isEqual:myTextField]) {
defaultsKeyForTextField = #"textfield_text";
}
[defaults setValue:textField.text forKey:defaultsKeyForTextField];
[defaults synchronize];
}
What seems to happen is that the text only saves when i enter in text manually.

As user TangZijian pointed out, textFieldDidEndEditing will be called when the textfield resigns first responder.
None of your code in print function do this.
Since set textfield as first responder and immediately resign it seems like a bad idea, you can move the code in textFieldDidEndEditing to print.
-(IBAction)print:(id)sender {
NSLog(#"text = %#",[textView text] );
NSArray *textArray = [[textView text] componentsSeparatedByString:#"\n"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *defaultsKeyForTextField;
if (textArray.count > 0) {
NSString *line1 = textArray[0];
[myTextField setText:line1];
defaultsKeyForTextField = #"textfield_text";
[defaults setValue:textField.text forKey:defaultsKeyForTextField];
[defaults synchronize];
if (textArray.count > 1) {
NSString *line2 = textArray[1];
[myTextField1 setText:line2];
}
}
[textView setText:#""];
[textView resignFirstResponder];
}

I think you should be using a the Editing Changed event to detect changes to your text fields value. Put this in your viewDidLoad method.
[myTextField addTarget:self
action:#selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
Then change your code to:
- (void)textFieldDidChange:(UITextField *)textField {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *defaultsKeyForTextField;
if ([textField isEqual:myTextField]) {
defaultsKeyForTextField = #"textfield_text";
}
[defaults setValue:textField.text forKey:defaultsKeyForTextField];
[defaults synchronize];
}

Related

Obj C - NSUserDefaults won't give back values to calculate, after loading the view

I am stuck with little problem. I have basic calculating app.
Viewcontroller.m
#import "ViewController.h"
#interface ViewController () <UITextFieldDelegate, UIAlertViewDelegate>
#end
#implementation ViewController
-(void)textFieldDidEndEditing:(UITextField *)textField
{
self.currentSettings = _currentSettings;
[self calculateThePrice];
}
-(void)calculateThePrice
{
float wynik = self.currentSettings.kwh * self.currentSettings.price;
self.priceLabel.text = [NSString stringWithFormat:#"%.02f %#", wynik , self.currentSettings.currency];
}
SettingsVC.m
#import "SettingsVC.h"
#interface SettingsVC () <UITextFieldDelegate>
#end
#implementation SettingsVC
#pragma mark - UserDefaults Implementation
-(void)viewWillAppear:(BOOL)animated
{
[self createCurrencyArray];
NSUserDefaults *priceDef = [NSUserDefaults standardUserDefaults];
NSString *priceDefText = [priceDef stringForKey:#"priceCall"];
_priceTextField.text = priceDefText;
NSUserDefaults *currencyDef = [NSUserDefaults standardUserDefaults];
[_currencyPicker selectRow:[currencyDef integerForKey:#"currencyCall"]
inComponent:0 animated:NO];
[priceDef synchronize];
[currencyDef synchronize];
}
-(void)viewWillDisappear:(BOOL)animated
{
NSString *textOfPriceTexField = _priceTextField.text;
[[NSUserDefaults standardUserDefaults] setObject:textOfPriceTexField forKey:#"priceCall"];
}
Now, the problem is when I want program to automatically-calculate, it won't. To have any result, I have to switch to Second View, choose a value from picker and then when I will go back, I have my result.
But...
- When I change value on 1st screen, result won't change. When I change value on 2nd scree, result won't change. But when I change value on PickerView - TADAH - result updates!
When I go to second view, and go back to first, then go again to second and go back to first, my result changes to "0.00 (NULL)"...
Any ideas where I did wrong? I think it is about NSUserDefaults, I tried many options, nothing worked, nor changed anything.
You need to synchronize NSUserDefaults when you set new values. You are using synchronize when you retrieve values.
Here you don't need 2 pointers to defaults and don't need synchronize:
NSUserDefaults *priceDef = [NSUserDefaults standardUserDefaults];
NSString *priceDefText = [priceDef stringForKey:#"priceCall"];
_priceTextField.text = priceDefText;
[_currencyPicker selectRow:[priceDef integerForKey:#"currencyCall"] inComponent:0 animated:NO];
Here you need synchronizes:
-(void)viewWillDisappear:(BOOL)animated
{
NSString *textOfPriceTexField = _priceTextField.text;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:textOfPriceTexField forKey:#"priceCall"];
[defaults synchronize];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSInteger selectedRow = [_currencyPicker selectedRowInComponent:0];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:selectedRow forKey:#"currencyCall"];
[defaults synchronize];
self.currentSettings.currency = [self.currencyArray objectAtIndex:row];
self.currentSettings.price = [self.priceTextField.text floatValue];
//[self userDidFinishSetting];
}
Try this code
-(void)viewWillDisappear:(BOOL)animated
{
NSString *textOfPriceTexField = _priceTextField.text;
[[NSUserDefaults standardUserDefaults] setObject:textOfPriceTexField forKey:#"priceCall"];
}
-(void)viewWillAppear:(BOOL)animated
{
[self createCurrencyArray];
NSUserDefaults *priceDef = [NSUserDefaults standardUserDefaults];
NSString *priceDefText = [priceDef objectForKey:#"priceCall"];
}
instead of stringForKey you can call objectForKey same as for integerForKey also you can call objectForKey. Actually you are setting the object not string or integer.

Save UITextField Data Programmatically

I got a UITextField as subview.
- (void)viewDidLoad {
[super viewDidLoad];
textField = [[UITextField alloc] initWithFrame:CGRectMake(21, 21, 159, 37)];
textField.borderStyle = UITextBorderStyleNone;
textField.font = [UIFont systemFontOfSize:15];
textField.placeholder = #"name";
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.keyboardType = UIKeyboardTypeDefault;
textField.returnKeyType = UIReturnKeyDone;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.textColor = [UIColor whiteColor];
textField.keyboardAppearance = UIKeyboardAppearanceDark;
textField.delegate = (id) self;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
[textField addTarget:self action:#selector(saveData:) forControlEvents:UIControlEventEditingDidEnd];
[self.view addSubview:textField];
}
-(void)saveData:(id)sender {
NSString *savestring = textField.text;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:savestring forKey:#"savedstring"];
[defaults synchronize];
}
To load the data (viewDidLoad)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *loadstring = [defaults objectForKey:#"savedstring"];
[textField setText:loadstring];
Now the problem is that it doesn't save and load the text of the UITextField.
First you need to enter some string in the Textfield and press return key, so that it will get a chance to call your "saveData" method and store the value in the NSUserDefaults. Just check all the values.
I found a solution:
textField.text = [defaults objectForKey:#"savedstring"];
Thanks everyone for your answers
"addSubview" after this method write to load the data method...
[self.view addSubview:textField];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *loadstring = [defaults objectForKey:#"savedstring"];
[textField setText:loadstring];

How to use UISwitch with NSUserDefault

defaults = [NSUserDefaults standardUserDefaults];
NSLog(#"%#",[defaults objectForKey:#"firsttime"])
if([[defaults objectForKey:#"firsttime"]isEqualToString:#"YES"])
{
UISwitch *onoff = (UISwitch *) sender;
if(onoff.on)
{
NSLog(#"yes on1 facebookswitch");
facebookSwitch.on = YES;
[userDefault setValue:#"true" forKey:#"facebooknotify"];
NSLog(#"on");
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
[validate alertCommonWithoutMessage:NSLocalizedString(#"val_message",nil) :NSLocalizedString(#"val_facebook_login",nil) :#"OK"];
facebookSwitch.on = YES;
NSLog(#"yes on2 facebookswitch");
}
else {
NSLog(#"val_facebook_conf");
[validate alertCommonWithoutMessage:NSLocalizedString(#"val_message",nil) :NSLocalizedString(#"val_facebook_conf",nil) :#"OK"];
facebookSwitch.on = NO;
[userDefault setValue:#"false" forKey:#"facebooknotify"];
NSLog(#"yes off1 facebookswitch");
I'm using this method,but sumtimes the response is null.
Try this code:
// add this code in your switch touch event
- (IBAction)YourSwitch:(UISwitch*)sender
{
if (UISwitch.on)
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:true forKey:#"Sound"];
[defaults synchronize];
}
else
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:false forKey:#"Sound"];
[defaults synchronize];
}
}
// add this code in your viewDidload .
BOOL isSound= [[NSUserDefaults standardUserDefaults] objectForKey:#"Sound"];
if (isSound){
_ref_slider.on=TRUE;
} else {
_ref_slider.on=FALSE;
}
i hope this code is useful for you.
As to why it's not working, the most common problem is [userDefault synchronize]
Also, rather than using string boolean values, why not use:
[userDefault setBool:YES forKey:#"facebooknotify"];
and then access by
BOOL notified = [userDefault boolForKey:#"facebooknotify"];

How can I put data from UITextField to IBAction string

I have UITextField named textField where user can save phone number with NSUserDefaults. Then I have IBAction to call that number. How can I put to that action a number what user have been saved to UITextField?
-(IBAction)callPhone:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:123456"]];
}
UPDATE
- (IBAction) saveBtnPresssed : (id) sender
{
myString1 = [[NSString alloc] initWithFormat:textField.text];
[textField setText:myString1];
NSUserDefaults *stringDefault = [NSUserDefaults standardUserDefaults];
[stringDefault setObject:myString1 forKey:#"stringKey"];
}
- (void)viewDidLoad
{
[textField setText:[[NSUserDefaults standardUserDefaults] objectForKey:#"stringKey"]];
[super viewDidLoad];
}
The string you are looking for is returned by:
[textField text];
If you saved that to user defaults then you can just:
-(IBAction)callPhone:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *phoneNumberString = [defaults objectForKey:#"key_you_saved_the_number_with"];
//... do what you need with that number here
}
EDIT:
[NSURL URLWithString:[NSString stringWithFormat:#"tel:%#"], [defaults objectForKey:#"stringKey"]];
so the resulting string should be "tel:" + the actual number from the text field instead of "tel:123456"
In your code setting the textfiled with the same string is not required.
Simply use:
(IBAction) saveBtnPresssed : (id) sender
{
myString1 = [[NSString alloc] initWithFormat:textField.text];
NSUserDefaults *stringDefault = [[NSUserDefaults standardUserDefaults] setObject:myString1 forKey:#"YOUR_KEY"];
}
This would set the string to your defaults and you can fetch the data as
NSString *pString = [defaults objectForKey:#"YOUR_KEY"];

Saving Automatically in NSStrings

I have three text fields: first name, last name, and age, also a photo. What can I do so that the information saves automatically, so that i dont have to click a button?
This is my ViewController.h:
#import <UIKit/UIKit.h>
#interface ContactViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
IBOutlet UIImageView *contactImageView;
IBOutlet UITextField *firstNameTextField;
IBOutlet UITextField *lastNameTextField;
IBOutlet UITextField *ageTextField;
}
- (IBAction)save:(id)sender;
- (IBAction)chooseImage:(id)sender;
#end
This is my ViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *frontName = [defaults objectForKey:#"firstname"];
NSString *lastName = [defaults objectForKey:#"lastname"];
int age = [defaults integerForKey:#"age"];
NSString *ageString = [NSString stringWithFormat:#"%i",age];
NSData *imageData = [defaults dataForKey:#"image"];
UIImage *contactImage = [UIImage imageWithData:imageData];
firstNameTextField.text = frontName;
lastNameTextField.text = lastName;
ageTextField.text = ageString;
contactImageView.image = contactImage;
}
- (void)viewDidUnload {
[contactImageView release];
contactImageView = nil;
[firstNameTextField release];
firstNameTextField = nil;
[lastNameTextField release];
lastNameTextField = nil;
[ageTextField release];
ageTextField = nil;
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)save:(id)sender {
[firstNameTextField resignFirstResponder];
[lastNameTextField resignFirstResponder];
[ageTextField resignFirstResponder];
// Create strings and integer to store the text info
NSString *frontName = [firstNameTextField text];
NSString *lastName = [lastNameTextField text];
int age = [[ageTextField text] integerValue];
UIImage *contactImage = contactImageView.image;
NSData *imageData = UIImageJPEGRepresentation(contactImage, 100);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:frontName forKey:#"firstname"];
[defaults setObject:lastName forKey:#"lastname"];
[defaults setInteger:age forKey:#"age"];
[defaults setObject:imageData forKey:#"image"];
[defaults synchronize];
NSLog(#"Data saved");
}
- (IBAction)chooseImage:(id)sender {
UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
contactImageView.image = image;
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissModalViewControllerAnimated:YES];
}
you will have to work with the <UITextFieldDelegate> protocol
Reference: UITextFieldDelegate Protocol
you will have to set
textField.delegate = yourViewController
and can then work with the protocol functions, that handle input and character changing of your textview.
for example you cound use
- (BOOL)textFieldShouldReturn:(UITextField *)textField
to save the textfield content when the user presses the return button =)
EDIT: probably this method is better suited for your needs - i was a bit tired yesterday when writing the post =)
- (void)textFieldDidEndEditing:(UITextField *)textField {
//save your textfied.text string here :)
}
You need to set the delegate of the UITextfield to the view controller in your viewDidLoad method like
firstNameTextField.delegate = self;
lastNameTextField.delegate = self;
ageTextField.delegate = self;
Your view controller needs to implement the UITextFieldDelegate Protocol method:
- (void)textFieldDidEndEditing:(UITextField *)textField {
//Do save Operations here
}
This will save only after the text is done editing. If you want to save as the user is typing, use
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *stringToSave=[textField.text stringByReplacingCharactersInRange:range withString:string];
//Identify text field by comparing textField with you text fields and do save operations
return YES;
}

Resources