This is a strange problem but I am perplexed on how to solve this - I have a UITableView that has custom UITableViewCells. Each UITableViewCell has two UITextFields and each UITextField is linked to a delegate that processes the textFieldDidEndEditing event. This works perfectly except in one instance.
Problem
The screen also has a 'Save' button and the problem arises when the user edits a UITextField and directly clicks the 'Save' button without clicking elsewhere in the screen. In such an event, the saveAction method is invoked before the textFieldDidEndEditing event and as a result the last edit of the user is lost.
I tried to debug using NSLog statements and found that while the textFieldDidEndEditing is indeed getting called, it is called after the saveAction event.
I thought about calling the textFieldDidEndEditing event from saveAction but that didnt make sense as I would have no idea about which UITextField is being edited.
Any suggestions are very much appreciated.
you could make a note of the text field that is active when the –textFieldDidBeginEditing: delegate method is called in your view controller
have an assigned property that points to the active text field and then in -saveAction send it -resignFirstResponder.
header:
#property (nonatomic, assign) UITextField * editingTextField;
m file:
-(void)textFieldDidBeginEditing:(UITextField *)textField{
self.editingTextField = textField;
}
-saveAction{
if(self.editingTextField)
[self.editingTextField resignFirstResponder];
//continue implementation
}
Related
I'm actually in big troubles on how to get the Text from a TextField (and optionally a TextView ).
I'll try to make it simple: I have my PostIt.xib which is composed of 2 labels (which I don't really care about) and also one TextField and one TextView. Here is how I tried to get the text from these:
First, in my PostIt.h :
#interface PostIt : UIView {
IBOutlet UITextField *titre;
IBOutlet UITextView *commentaire; }
Then secondly, in my PostIt.m : (the real action of this method is that it close a view and normally throw back the information I want to get to another view, here: parent )
-(IBAction)doubleTap:(UITapGestureRecognizer *)recognizer{
[_parent setTitre:titre.text];
[_parent setCommentaire:commentaire.text];
[_parent setIsEdited:true];
[self removeFromSuperview]; }
My problem here is, when I call a NSLog (for example) to show me the Strings which are caught (probably a mistake here? sorry) it show me every time : (null)
I have been looking and trying a lot of answer i found but no one seems to be able to solve my problem...
If someone could help me it will be really nice, thanks in advance :)
Is there any more code pertaining to the UITextField?
Based on what I see here you need you first convert the input from the UITextField
into a string and then you can set the string where you want.
Updated to add the conversion code,
NSString *stringFromTextField = [yourTextField text];
Here is some more details,
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *yourTextField;
#end
Your Action,
- (IBAction)yourAction:(id)sender {
//Converting UItextfields into strings
NSString *stringFromTextField = [self.yourTextField text];
}
Here is a sample project I made for you on GitHub -
stringFromTextView
You should try to input to your code an object part if that's not already done, where you could directly pick up the data that you need and that's also from here that you should update your view.
I've subclassed UITextField in order to show a tool bar with a button when the keyboard is shown.
UITextField SubClass:
- (void)methodName
{
//Do stuff
}
When the user presses the button and methodName is triggered inside the UITextField.
I want the same method to be triggered also inside the current ViewController for some more specific code additions relevant only to the current ViewController
I thought about getting a referral to the topviewcontroller and trigger my method from inside methodName in the UITextField subClass but it doesn't feel right.
What's the right way to do the above?
I would look into the delegation pattern. It may make sense to have your view controller be the delegate of your text field so it is informed when your text field is pressed.
Something like:
textField.delegate = viewController;
And have your view controller class implement the appropriate UITextFieldDelegate methods so that it is notified when editing begins/ends.
I have the following code:
#interface MyCell : UITableViewCell<UITextFieldDelegate>
{
IBOutlet UITextField *txtFields;
}
- (IBAction)textFieldAction:(id)sender;
#property (nonatomic,retain) IBOutlet UITextField *txtFields;
#end
I also have the following delegate function:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return NO;
}
However, I notice that it's NEVER being called. I set the delegate from the interface builder as well as from code as per: [txtFields setDelegate:self]; but neither seems to work. Is there something else i'm missing for this?
You are obviously using this in conjunction with a UITableView. First, if you want to support user interaction, the txtFields must be a subview of the cell's contentView, not the backgroundView.
Assuming that the txtFields object is a subview of the contentView, then lets look at the connections.
The tableView has a a method cellForRowAtIndexPath: where you either return a new cell or a recycled cell. At the very bottom of that cell, add:
NSLog(#"textFields=%# delegate=%#", cell.txtFields, cell.txtFields.delegate);
assert(cell.txtFields.delegate == cell); // lets make sure this is proper
If in fact both arguments are there, you now know that the txtFields object is in the proper container (contentView), that the property is working, and that the delegate is set to the cell.
If that is all proper and you do not get the keyboard when you tap, then most likely something else is overlaying the txtFields - some other transparent view and its eating the touches.
In that case you should throw together a little demo app using the MyCell class, with even just one hardcoded cell, that demonstrates the problem, then upload that (zipped) to your DropBox account where others like myself can take a look at it and find the problem.
Try removing:
{
IBOutlet UITextField *txtFields;
}
since you have a #property already.
Also, did you #synthesize txtFields;?
I have a tableview with UITextFields to build a form. I then have a button in the toolbar which launches a modal view controller to select some data which is then passed back to the tableview. However, the new data that was selected does not get refreshed into the UITextField using textField.text = valueReturnedFromModal syntax. Is there something I'm missing?
I see that the data is being returned properly from the modal so that is not the issue. I'm just having trouble forcing the UITextField to refresh with the new data. I've tried forcing a reloadData on the tableview as well.
So from the modal view, here's the code that passes data back:
- (void)doneAccountSelection:(id)sender
{
[delegate didSelectAccount:currentAccount];
[self dismissModalViewControllerAnimated:YES];
}
and here's the actual method in the delegate:
- (void)didSelectAccount:(SFAccount *)selectedAccount
{
//Ensure a valid deal exists for the account to be attached to
[self createDealObjectIfNeeded];
//Set the deal account
[self.deal setAccount:selectedAccount];
//Refresh the text fields
//Tag 3: Account Name field
UITextField *acct_name = (UITextField *) [self.view viewWithTag:3];
[acct_name setText:self.deal.account.field_acct_name_value];
//Tag 4: Account City field
UITextField *acct_city = (UITextField *) [self.view viewWithTag:4];
[acct_city setText:self.deal.account.field_acct_city_value];
//Save the context changes. A new deal gets created above if one does not exist.
if ([self saveModel]) NSLog(#"Acct object created, attached to deal successfully!");
[self.tableView reloadData];
}
Would you mind posting the code that sets the text fields data and the code that passes the data back to the table view?
Answer:
It appears that you are properly setting the data, however, you are dismissing the modal view controller after sending the delegate message. In this scenario, the table view is not even created until after the dismissModalViewControllerAnimated: has ended. Which means the textfields are NULL until the view is present. What I suggest is call
[self dismissModalViewControllerAnimated:YES];
as the first line in the didSelectAccount: delegate method. This would dismiss the modal view and then continue on with your setting the data to valid textfields as -viewWillAppear: / -viewDidAppear: would have already been called. Everything seems ok it's just the order that may be tripping you up. Although
-dismissModalViewControllerAnimated:
is passed to its parent if a view controller does not have a modal view (because it is the modal view), it seems more appropriate to call this method in the delegate method where you will eventually manipulate the view due to new data, etc.
use this after getting Value in text field:
[self.tableView ReloadData];
After some serious debugging found that self.account was being used in cellForRowAtIndexPath to set the initial UITextField values within the UITableViewCell. Then after modal selection completed, I was only updating the account reference for the deal object and not updating the self.account object.
I then added to this by creating a new method called updateTextFieldsAfterModalFinished and moved the code to update the UITextFields there. This method was then called from didSelectAccount which is the delegate method for modal view that is dismissed. Things are now working as expected and the UITextFields get updated after modal selection is finished.
I have made an application in which user may generate as many UITextField as he/she wants and those will be automatically placed over a UIView. Functionality is that user may drag the any of the UITextField at any point of screen.Till this part every thing is quite working. Now if he wants to edit the UITextField he taps(2 times) on UITextField and edits.This part of mine is only working for the recent generated UITextField not for all. How can i do this? I fnay one wants my previous code i can post. Plese respond it sonn. Thanks in advance.
add textFieldArray to .h file then specify <UITextFieldDelegate> and
sythesize that array.
while creating the each textfield
specify delegate like this
mytextF1.delegate=self;
mytextF2.delegate=self;
.....
after that add all text field object to an textFieldArray which should be declared .h file and synthesize them .(dont forget to alloc and init this array in ur viewdidload).
self.textFieldArray=[[NSMutableArray alloc]init];
then add each text field to this array
[self.textFieldArray addObject:mytextF1];
[self.textFieldArray addObject:mytextF2];
.......
then use this delegate methode to update
- (void)textFieldDidBeginEditing:(UITextField *)textField{
for (UITextField *textF in self.textFieldArray) {
[textF setText:[textField text]];
}
}