I am making a simple application that has a TextField and a TextView
Whatever we write in textfield will get updated in textview (Both are in a single View, and it is the Root view).
the textfield will get updated every time i hit any key in the keyboard.
I know that the delegate method "textfielddidEditing" helps , but it only helps when we click on the field or click back. I want the method that invokes every time when i hit anything in the keyboard.
Any help is appreciated.
I'm still learning iOS
Please use below textfield delegate method. Its easy and simple to use with all appen and delete mechanism. You can delete multiple characters too by selection. Just store newString value to your textView
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSMutableString *newString = [NSMutableString stringWithString:textField.text];
if (range.length > 0) {
[newString replaceCharactersInRange:range withString:string];
}
else {
[newString appendString:string];
}
NSLog(#"%#",newString);
return YES;
}
You can use UITextField Delegate method. It invokes every time when you hit anything in the keyboard. Write your code as per your requirement..
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length>0)
{
self.yourtextview.text=textField.text;
}
return YES;
}
Hope it helps you..
The above code mentioned by Vidhyanad900 will work. But its if would fail in case a user deletes the text. (Hits backspace or selects complete text and deletes it)
Hence Modifying the code
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int iNewLength = [textField length];
if([text isEqualToString:#""]) //If text is deleted
{
if([textField selectedTextRange]) //If Text is Seleceted And Deleted
iNewLength = [textField length] - [textField selectedRange].length;
else
iNewLength = [textField length] - 1;
}
if (iNewLength > 0)
{
self.yourtextview.text=textField.text;
}
return YES;
}
Related
I want to detect that text has end on text field when user press delete button to delete the text in the textfield.So when user reach to end of deleting the text then i want to detect it.
I have use following to achieve the task but i am unable to do it.Problem is event after textfield become empty then it does not detect.When i again type after textfield become empty then it detects but that time size is 1 not zero.Please suggest me some idea?
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.txt_Search)
{
NSLog(#"out if");
if (![string isEqualToString:textField.text] )
{
if([self.txt_Search.text length]==0)
{
NSLog(#"finished writing");
}
}
}
return YES;
}
You can check the range to do the trick:
-(BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
NSRange backspaceEndRange = NSMakeRange(0, 1);
if (NSEqualRanges(range, backspaceEndRange)){
NSLog(#"finished writing");
}
return YES;
}
i have a little problem.
There are two textFields in my TableView which set the property of an object. In order to do so i want to force the user to write something in the textField before the string is actually been set to the object. So basically a simple ([textField.text length] > 0) thing.
But i want that the user have to write strings in both the two textFields to finally enable the "Done"-Button.
I solved this earlier but with only one text Field with the following UITextFieldDelegate method.
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newText = [theTextField.text stringByReplacingCharactersInRange:range withString:string];
self.doneBarButton.enabled = ([newText length] > 0);
return YES;
}
My solution for the new problem, so now with two textFields is this one:
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newText = [theTextField.text stringByReplacingCharactersInRange:range withString:string];
if ([theTextField.placeholder isEqualToString:#"textField1"]) {
if ([theTextField.text length] > 0) {
enabledVokabel = YES;
} else {
enabledVokabel = NO;
}
}
if ([theTextField.placeholder isEqualToString:#"textField2"]) {
if ([theTextField.text length] > 0) {
enabledUebersetung = YES;
} else {
enabledUebersetung = NO;
}
}
self.doneBarButton.enabled = (enabledVokabel && enabledUebersetung);
return YES;
}
So i want the doneBarButton been enabled when both of the textFields (textField1 and textField2) are filled with text. But i want it that way that if the user has deleted the text he/she just wrote in the doneBarButton is disabled as soon as the textFields are empty.
It doesn't work that way. Do you have a solution? Or maybe a better way to solve it?
Either just connect value changed in interfacebuilder to a IBAction method in any of the classes you have in your view. Or you can do it in code with:
[textField addTarget:self
action:#selector(myIBActionMethod:)
forControlEvents:UIControlEventEditingChanged];
And check the length of the input.
You can of hook up both textfields to the same method and check the length of both textfields every time its called if you have IBOutlets to them both.
I'd keep a reference for both UITextViews, lets say.-
IBOutlet UITextView *textView1;
IBOutlet UITextView *textView2;
properly linked to your xib/storyboards. Also, I'd rather use
- (void)textViewDidChange:(UITextView *)textView
callback. According to shouldChangeCharactersInRange docs, it looks like this method is called before actually changing the text.
As for the enabled condition, it would look something like this.-
self.doneBarButton.enabled = [textView1.text length] > 0 && [textView2.text length] > 0;
I have a text field where I want to insert a phone number. The problem is that I use number pad and there is not any enter key and I without that key I don't know how to close the text field.
Is there any way of checking how many number os characters there are in a text field and close the number pad when there are X chars?
Sorry for my english and sorry for the noob question but I am just starting with ObjC.
Thanks *
Sorry guys, I forgot to tell you that I already have tried this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.text.length== 9) {
[textField resignFirstResponder];
}
return YES;
}
Yes, you have two choices in my opinion, you can:
A. Check the number of chars returned in delegate method shouldChangeTextInRange and then if your limit is reached resign first responder (when you resign first responder the keyboard dismisses,
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ( textView.text.length + (text.length - range.length) == 10) //or whatever value you like
{
[textField resignFirstResponder];
}
}
Or B:
Override the touchesEnded method of your view and call resignFirstResponder, so that when the user touches the view outside the textField, the keyboard dismisses. - this is what I do in my app.
Like this:
Just add this method to your viewController, it will be called automatically when the touch in the view ends, in this method you simply resignFirstResponder and the keyboard will disappear.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[textField resignFirstResponder];
}
I think it's better to do this in touchesEnded than began, it 'feels' nicer to have the keyboard dismiss when you lift your finger from the view, rather than when to initially touch it.
I found that resignFirstResponder do not include the last char typed. I had to do it in this way,
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
DLog(#"Existing: %#, string: %#, range:(%lu, %lu)", textField.text, string, (unsigned long)range.location, (unsigned long)range.length);
if (textField == field2.textField) {
if ( textField.text.length + (string.length - range.length) == kMyNumberLength) // e.g. 10
{
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
[textField resignFirstResponder];
}
if (textField.text.length + string.length - range.length > kMyNumberLength) {
return NO;
} else {
return YES;
}
}
return YES;
}
Swift
when reaching the maximum number of characters, add the new char to the current text in the textfield and then dismiss the keyboard
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let maxLength = 5
let currentString: NSString = textField.text! as NSString
let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
if newString.length == maxLength {
textField.text = textField.text! + string
textField.resignFirstResponder()
}
return newString.length <= maxLength
}
Every time a user adds a number, the delegate of your text field will be notified through this method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger length = [[textField text] length] - range.length + string.length;
if (length == ...) ...
}
You can set up your delegate in such a way as to watch the length of the modified content of your text field, and close the field when the expected length is reached.
However, this has a high potential to frustrate your users a lot: they would make a mistake entering the last character every now and then, and the field is going to close on them, not letting them correct the problem. A better approach is to dismiss the pad when users tap away from your text field, which keeps end-users in control of what is going on:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[textField resignFirstResponder];
}
You can just put a toolbar with a Done on it, on the click on that button you can hide keyboard and toolbar as well.
-(IBAction)doneButtonClicked:(id)sender{
[yourTextField resignFirstResponder];
[toolBar setHidden:YES];
}
or you can use this custom tool
Had issues with some of the suggestions above not retaining the last character entered.
I found this worked well for me.
Method simply examines the length of the text as it is building up and then runs [textField resignFirstResponder] to dismiss.
All usual textField delegates will run for the textField at point field loses focus and keyboard is dismissed.
- (void)textFieldDidChangeSelection:(UITextField *)textField {
NSLog(#"textField.text: %#", textField.text);
if (textField.text.length == 4) // If 4 is your max-length
[textField resignFirstResponder];
}
Use this textfield delegate method to find out the length of textField.text
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int textLength = [textField.text length] + 1;
return YES;
}
What I would like to do is to add some text at the beginning of UITextField that cannot be deleted. I add this text when the user taps on UITextField like this:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
if (textField.text.length == 0) {
textField.text = #"myText";
}
return YES;
}
How do I prevent the user from deleting this text in a normal way? (without adding a separate UILabel on top of the TextField, for example).
Thanks in advance!
You can implement this code in shouldChangeCharactersInRange delegate method.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length == 1 && [string isEqualToString:#""]) {//When detect backspace when have one character.
textField.text = #"myText";
}
return YES;
}
Checkout shouldChangeCharactersInRange in the UITextFieldProtocolReference
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
the text field calls this method whenever the user types a new
character in the text field or deletes an existing character.
So, you have control on whether text actually gets changed so you can insert your custom logic in that delegate callback enforcing whatever rules about what can change.
Use this
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([[textField text] length]==LENGTH_OF_TEXT && [string isEqualToString:#""])
{
return NO;
}
else
return YES;
}
Hope it helps you.
I want to set a max length to my UITexField but this is inserted in a UIAlertView,
I'm trying to find out the right information to solve this problem,on this beautiful site but there is nothing.
Could someone help me to this?
I think this is a better implementation of the UITextFieldDelegate method, as it will not remove the text end in front of the users eyes, it just prevents the user from typing in more text.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (newString.length > MAXLENGTH)
{
return NO;
}
return YES;
}
Don't forget to implement the UITextFieldDelegate protocol, and set your controller as the delegate of the text field (see Anoop Vaidya answer)
As you can access the alertView's textField by
UITextField *theTitleTextField = [alertView valueForKey:#"_bodyTextLabel"];
If you want to find your's textfield added, then use textFieldAtIndex: as suggested by Martin R.
Then implement UITextFieldDelegate protocol.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField.text length] > MAXLENGTH) {
textField.text = [textField.text substringToIndex:MAXLENGTH-1];
return NO;
}
return YES;
}