Set Textfield Data on click save button in iphone - iphone

I have a modalviewcontroller and have two buttons on it: Cancel and Save. There is a UITextField which is editable.
Whenever I click on save button I do save it but the text doesnot get save because when I click on the button to open the modalviewcontroller, the text disappears. Dont know whats wrong with my code.
Here is my code :
- (void)viewWillAppear:(BOOL)animated {
self.cancel = self.navigationItem.leftBarButtonItem;
self.save = self.navigationItem.rightBarButtonItem;
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(cancelAction)];
self.navigationItem.leftBarButtonItem = cancelButton;
[cancelButton release];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStylePlain target:self action:#selector(saveAction)];
self.navigationItem.rightBarButtonItem = saveButton;
[saveButton release];
[super viewWillAppear:animated];
}
-(IBAction) cancelAction{
[[self parentViewController] dismissModalViewControllerAnimated:YES];
}
-(IBAction) saveAction{
NSString *text = [textFieldBeingEdited text];
[textFieldBeingEdited setText:text];
[self setDescription:text];
[[self parentViewController] dismissModalViewControllerAnimated:YES];
}
I am not sure if I have to use the following code to save the text in textfield :
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self dismissModalViewControllerAnimated:YES];
}

I don't see in your code anywhere that you are setting the text in the UITextField when the view appears. You can add some code to your viewWillAppear method to set the text when the view appears, such as:
[textField setText:[self description]];
(It looks like you are storing the NSString in the description variable.)
Also, if this is some kind of string that could be considered a User Default, you can store the string there. I've used this before and it populates my UITextField nicely.
Code Example:
-(void)viewDidLoad
{
stringValue = [[NSUserDefaults standardUserDefaults] stringForKey:#"string"];
[textField setText:stringValue];
}
-(IBAction)saveAction
{
stringValue = [textField text];
[[NSUserDefaults standardUserDefaults] setObject:stringValue forKey:#"string"];
}

Related

Update the User Interface with dispatch_get_global_queue and Web Call

I am trying to learn to use dispatch_get_global_queue to perform a web call asynchronously. Basically, I need to update the User Interface depending on the user's location. I started using dispatch_get_global_queue because the user interface was unresponsive while the web call was performed.
Now, my problem is that the buttons do not appear correctly when buttonUpdate is called. One button is supposed to be black, and the other is green. However, now they both appear the default blue. Also, the words/title of the buttons do not appear until I click on one of them. Anyone know why? Thank you!
I have this method called preButtonUpdate that calls the buttonUpdate method asynchronously:
-(void)preButtonUpdate {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
[self buttonUpdate];
});
}
The preButtonUpdate method is called in viewDidAppear and appReturnsActive:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self preButtonUpdate];
//other code
}
- (void)appReturnsActive {
[myTimer invalidate];
myTimer = nil;
//ONLY WANT TO PERFORM THE UPDATE IF VIEWING THE PROFILE VIEW CONTROLLER
UIViewController *currentVC = self.navigationController.visibleViewController;
NSString * name = NSStringFromClass([currentVC class]);
if ([name isEqualToString:#"ProfileViewController"]) {
[self preButtonUpdate];
}
}
Then, the preButtonUpdate calls the buttonUpdate method, which performs the web query and updates the user interface:
-(void) buttonUpdate {
[locationManagerProfile stopUpdatingLocation];
NSString *userLatitude =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate
getUserLatitude];
NSString *userLongitude =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate
getUserLongitude];
NSString *placeLatitude = [[NSUserDefaults standardUserDefaults]
stringForKey:#"savedLatitude"];
NSString *placeLongitude = [[NSUserDefaults standardUserDefaults]
stringForKey:#"savedLongitude"];
NSString *distanceURL = [NSString stringWithFormat:#"http://www.website.com/page.php?
lat1=%#&lon1=%#&lat2=%#&lon2=%#",userLatitude, userLongitude, placeLatitude,
placeLongitude];
NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL
URLWithString:distanceURL]];
NSString *distanceInFeet = [[NSString alloc] initWithData:distanceURLResult
encoding:NSUTF8StringEncoding];
if ([distanceInFeet isEqualToString:#"1"]) {
UIBarButtonItem *btnGo = [[UIBarButtonItem alloc] initWithTitle:#"Button A"
style:UIBarButtonItemStyleBordered target:self action:#selector(actionA)];
self.navigationItem.rightBarButtonItem = btnGo;
[self.navigationItem.rightBarButtonItem setTintColor:[UIColor
colorWithRed:44.0/255.0 green:160.0/255.0 blue:65.0/255.0 alpha:1.0]];
UIBarButtonItem *btnGoTwo = [[UIBarButtonItem alloc] initWithTitle:#"Button B"
style:UIBarButtonItemStyleBordered target:self action:#selector(actionB)];
self.navigationItem.rightBarButtonItem = btnGoTwo;
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:btnGo,
btnGoTwo, nil];
}
if ([distanceInFeet isEqualToString:#"0"]) {
UIBarButtonItem *btnGo = [[UIBarButtonItem alloc] initWithTitle:#"Button C"
style:UIBarButtonItemStyleBordered target:self action:#selector(actionC)];
self.navigationItem.rightBarButtonItem = btnGo;
[self.navigationItem.rightBarButtonItem setTintColor:[UIColor
colorWithRed:44.0/255.0 green:160.0/255.0 blue:65.0/255.0 alpha:1.0]];
UIBarButtonItem *btnGoTwo = [[UIBarButtonItem alloc] initWithTitle:#"Button B"
style:UIBarButtonItemStyleBordered target:self action:#selector(actionB)];
self.navigationItem.rightBarButtonItem = btnGoTwo;
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:btnGo,
btnGoTwo, nil];
}
}
UI Update is always done on the main thread. So keep your UI update code out of the despatch queue
Keep [self buttonUpdate]; out of the dispatch_async block
-(void)preButtonUpdate {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
[self buttonUpdate];
});
}
Unblocking Your User Interface - Apple Developer
EDIT:
Put the if condtion code just outside the dispatch_async block

Using an inputAccessoryView UIToolbar for Multiple UITextField's

I have a UIToolbar that I'm adding as an inputAccessoryView to three UITextFields with numeric keypads. On this UIToolbar I have a cancel and a done button to dismiss the keyboard as per this post: trying to add done button to Numeric keyboard. This works great for one UITextField, which can be easily identified. However, I'm trying to use the same code for three UITextFields. Here's what I have:
- (void) viewDidLoad
{
[super viewDidLoad];
// weight, numberOfDrinks, and drinkingDuration are UITextFields set up in Storyboard.
// I implemented the UITextFieldDelegate protocol in the .h file and set the UITextField's delegates to the owning ViewController in Storyboard.
self.weight.delegate = self;
self.numberOfDrinks.delegate = self;
self.drinkingDuration.delegate = self;
}
- (void) textFieldDidBeginEditing:(UITextField *)textField {
UIToolbar *doneToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
doneToolbar.barStyle = UIBarStyleBlackTranslucent;
// I can't pass the textField as a parameter into an #selector
doneToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancelKeyboard:)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneWithKeyboard:)],
nil];
[doneToolbar sizeToFit];
textField.inputAccessoryView = doneToolbar;
}
- (void) cancelKeyboard: (UITextField *) textField {
textField.text = #"";
[textField resignFirstResponder];
}
- (void) doneWithKeyboard: (UITextField *) textField {
[textField resignFirstResponder];
}
I get an "unrecognized selector sent to instance" error because the cancelKeyboard and doneWithKeyboard methods aren't being passed the textField parameter they need. Any ideas how to implement this properly?
Thanks!
Ben
use globle object in .h file
UITextField *SelectedTextField;
// In did begin editing method define
SelectedTextField = textField;
Then use it on your method to resign or show.
It would help for you.
If you just want to dismiss the keyboard in the current view controller, you can call the endEditing method of the view property of the view controller:
[self.view endEditing];

How to refresh UITableViewController in iphone/iPad

-(void)reloadView{
NSLog(#"IN RELOAD VIEW ");
[[self tableView] reloadData];
}
- (void)viewDidLoad {
UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
[self navigationItem].rightBarButtonItem = barButton;
[activityIndicator startAnimating];
[self callStudentsWebService];
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
[self setTitle:#"Students"];
self.navigationController.toolbarHidden = NO;
self.navigationController.toolbar.barStyle = UIBarStyleBlack;
UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithTitle:#"Add Student" style:UIBarButtonItemStyleBordered target:self action:#selector(addStudent)];
UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *import = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemOrganize target:self action:#selector(addStudent)];
NSArray* toolbarItems = [NSArray arrayWithObjects:add,flexible,import, nil];
self.toolbarItems = toolbarItems;
}
Above is my Code in a Class which is a subclass of UITableViewController.
Now my problem is when I come onto the screen First Time it get the records from web service from the method [self callStudentsWebService] . Now i have a button in uitoolbar in the same view which updates the list . I am calling the reloadView method to refresh the List but it calls the numberOfRowsInSection and viewDidLoad method but does not call cellForRowAtIndexPath method. But when i goto other screen and come back again it does refresh my List from start.
What could be the reason ?? Please help i am new in iPad Development. And i m doing all this in iPad.
Thanks alot
EDITED
#interface StudentsList : UITableViewController {
DetailViewController *detailViewController;
UIToolbar *toolbar;
UIActivityIndicatorView *activityIndicator;
}
May be your data.count is 0? If there is some data it should call cellForRowAtIndexPath after [[self tableView] reloadData];
Do the refresh code in another separate method -(void)refreshData then call this whenever you want such as in -viewDidLoad or on a button tap...
Try to call -(void)reloadView from
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self reloadView];
}

How to set action to the backButtonItem on the navigation bar?

How to set action to the backButtonItem on the navigation bar? I have a navigation bar, when I'm pressing the back button, I need to alert some message to the user, and only after user's reaction - return to the previous view. How can I do it? Thanx!
- (void)viewDidLoad
{
[super viewDidLoad];
//no one field don't changed yet
isDirty = FALSE;
//edited user
//set default values
newData = [data copy];
//setting navigation controller rigth button
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Save"
style:UIBarButtonSystemItemDone
target: self
action: #selector(saveBtnUserClick)];
self.navigationItem.rightBarButtonItem = rightButton;
[rightButton release];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonSystemItemDone
target: self
action: #selector(backBtnUserClick)];
self.navigationItem.backBarButtonItem = leftButton;
[leftButton release];
}
//and my method for reaction
-(IBAction) backBtnUserClick
{
NSLog(#"\n Back pressed");
//back to previous view
[self.navigationController popViewControllerAnimated: TRUE];
}
Add the < UINavigationControllerDelegate > in the header file and use this in the .m
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
//insert your back button handling logic here
// let the pop happen
return YES;
}
This sounds like a job for UIAlertView. Instead of calling popViewControllerAnimated: in your IBAction methods, alloc/init a UIAlertView and present it. Then, when the user taps a button on the UIAlertView, dismiss the UIAlertView and call popViewControllerAnimated:.
- (IBAction)backBtnUserClicked:(id)object {
UIAlertView *av = [[[UIAlertView alloc] initWithMessage:#"Wait!"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil] autorelease];
[av show];
}
In your UIAlertViewDelegate methods call popViewControllerAnimated:.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
[[self navigationController] popViewControllerAnimated:YES];
}
To set the action on the back button:
[[[self navigationController] leftBarButtonItem] setTarget:self];
[[[self navigationController] leftBarButtonItem] setAction:#selector(backBtnUserClicked:)];

ABPersonViewController ... no back button

I have a simple project based off the "Navigation Based application" project type. The RootViewController has a list of rows with some names for contacts, and a button which should take them to that contact's details page with ABPersonViewController.
I have all the hooks working and I show the correct ABPersonViewController by pushing it on the navigation stack... but it doesn't have a Back button! The app gets stuck because there's no way to get back to my app. How do I enable the back button? Would appreciate some help.
Here's the relevant code:
- (void) nameButtonClicked: (id) sender
{
UIButton *button = (UIButton *) sender;
NSLog(#"name button clicked... record_id = %i", button.tag);
ABRecordRef contact_data = ABAddressBookGetPersonWithRecordID(address_book, button.tag);
ABPersonViewController *ab = [[ABPersonViewController alloc] init];
[ab setPersonViewDelegate:self];
[ab setDisplayedPerson:contact_data];
ab.allowsEditing = YES;
[self.navigationController pushViewController:ab animated:YES];
[ab release];
}
if you cant find the system back button you can always create one yourself.
- (void) nameButtonClicked: (id) sender
{
UIButton *button = (UIButton *) sender;
NSLog(#"name button clicked... record_id = %i", button.tag);
ABRecordRef contact_data = ABAddressBookGetPersonWithRecordID(address_book, button.tag);
ABPersonViewController *ab = [[ABPersonViewController alloc] init];
ab.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Back",nil) style:UIBarButtonItemStyleDone target:self action:#selector(ReturnFromPersonView)];
[ab setPersonViewDelegate:self];
[ab setDisplayedPerson:contact_data];
ab.allowsEditing = YES;
[self.navigationController pushViewController:ab animated:YES];
[ab release];
}
- (void)ReturnFromPersonView{
[self.navigationController popViewControllerAnimated:YES];
}
good luck =]
btw- if you dont like the "done" button style, you can always use an custom button style for the back button arrow like look.