Moving the focus of a textfield to another based on conditions - iphone

I have 10 textfields, each of which could hold at most one character. When I enter a character in the first textfield, the focus should automatically move to the next textfield and so on. That is, as soon as the first character is entered in a textfield, the focus should shift to the next. That is, the next textfield should become the first responder. I have written the below code, used the textfield delegate method.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if([myCharSet characterIsMember:c])
{
int previousTag = textField.tag;
if([textField.text length] > 0)
{
if((previousTag == 9) && ([textField10.text length] >0))
{
return NO;
}
UITextField *tempField=(UITextField *)[self.view viewWithTag:previousTag+1];
if([tempField.text length] > 0){
[tempField resignFirstResponder];
return NO;
}
[tempField becomeFirstResponder];
return YES;
}
}
else{
return NO;
}
}
return YES;
}
But I am not getting the desired results. When I type a character its entered in the first textfield, but the focus is not shifting to the next, though when I type the 2nd character, it is entered in the next textfield.
Similarly, I need to write a delete function such that when I delete a textfield, the focus automatically shifts to the previous textfield.
Any answers will be appreciated. Thanks.

You can always return NO and change the textField text manually. I guess what you need is something like this.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];
int previousTag = textField.tag;
if ([string isEqualToString:#""]) {//backspace button
if (previousTag==0) {//added to prevent crashing in first tf
return YES;
}
UITextField *tempField2=(UITextField *)[self.view viewWithTag:previousTag-1];
textField.text=string;
[tempField2 becomeFirstResponder];
return NO;
}
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if([myCharSet characterIsMember:c])
{
if((previousTag == 9) && ([textField10.text length] >0))
{
return NO;
}
UITextField *tempField=(UITextField *)[self.view viewWithTag:previousTag+1];
if([tempField.text length] > 0)
{
textField.text=string;
[tempField resignFirstResponder];
return NO;
}
textField.text=string;
[tempField becomeFirstResponder];
return NO;
}
else{
return NO;
}
}
return YES;
}

-shouldChangeCharactersInRange gets called before text field actually changes its text. So you will be getting the old value in the string. Add the line at the beginning of your method. It should fix your problem.
string = [textField.text stringByReplacingCharactersInRange:range withString:string];

Related

Iphone should block 0 number in the keyboard

I've been writting iphone application in xcode, there is a form that contain phone number field. It must be contain 10 digits. If the user press 0 firstly in the keyboard, application must not write it.
For instance, phone number 05551234567, user can be only write 5551234567. If the user press 0, nothing happen.
First of all you should use
textView.keyboardType = UIKeyboardTypePhonePad
to choose the correct type of keyboard, so that you will be able to enter just numbers.
Secondly you must implement a UITextViewDelegate, set it as the text view delegate and implement a custom
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
that will check if you are trying to insert a 0 at the beginning of the content and return NO in that case.
If you are using a UITextField everything is the same, the only diffeference is that you will use UITextFieldDelegate and implement
- (BOOL)textField:(UITextField *)textField shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
Try following method.
by using below method user cannot enter 0 in textfield
- (BOOL)textField:(UITextField *)TextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"123456789"];
for (int i = 0; i < [string length]; i++)
{
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c])
{
return NO;
}
}
return YES;
}
And if you want that user cannot enter 0 only first place then use method like below
- (BOOL)textField:(UITextField *)TextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"123456789"];
if ([TextField.text length]<=0)
{
for (int i = 0; i < [string length]; i++)
{
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c])
{
return NO;
}
}
}
return YES;
}
I hope this will help you.

How to set the character limit limit in three UITextfield [duplicate]

This question already has answers here:
Set the maximum character length of a UITextField
(46 answers)
Closed 8 years ago.
I have three Textfield.
1.textField1 = 15 charecter
2.textField2 = 50 charecter
3.textField3 = 50 charecter
Code snippet
if (textField1 .text.length <15 && textField2 .text.length <50 &&
textField3 .text.length <50) {
return YES;
}else{
return NO;
}
How to set the limit of three UITextfield.
Thanks in advance
try like this,
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSUInteger length = [textField.text length] + [string length] - range.length;
if([textField isEqual:textField1])
{
if(length<15)
return YES;
else
return NO;
NSLog(#"1");
}
else if([textField isEqual:textField2] | [textField isEqual:textField3])
{
if(length<50)
return YES;
else
return NO;
NSLog(#"2 or 3");
}
}
This delegate permit to limit to nbChar a Uitexfield :
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField.text length] >=nbChar) {
textField.text = [textField.text substringToIndex:nbChar];
return NO;
}
return YES;
}
The Problem with some of the answer given above is, For example I have a text field and I have to set a limit of 15 characters input, then it stops after entering 15th Character. but they Don't allow to delete. That is the delete button also don't work. As I was facing the same problem. Came out with the solution , Given Below. Works Perfect for Me
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField.tag==6)
{
if ([textField.text length]<=30)
{
return YES;
}
else if([#"" isEqualToString:string])
{
textField.text=[textField.text substringToIndex:30 ];
}
return NO;
}
else
{
return YES;
}
}
I am having a text field, whose tag I have set "6"
and I have restricted the max char limit = 30 ;
works fine in every case. In the same way you can set tag for other textfields and define limit over them in the same way.

How to automatically advance cursor to next field when user types a certain number of characters

I have a sign up page for my app. Users are prompted to enter a cell number and a four digit PIN for use in the app. There are three cell fields to help with standardization of the cell format--the first field is three digits and holds the area code, the second field is also three digits, and the last field is four. The PIN field comes next. I want the next field to become active when the user enters the correct number of digits in a given box. For example, when someone types in three digits of the area code, the cursor should progress to the next box.
I've gotten it to work so that if one continues typing the cursor will move. However, it only moves after the next digit is typed (for example, you type three digits of the area code, then type another digit, and that digit will appear in the next box along with the cursor; the cursor does not move after typing only three digits). Additionally, the method I am using appears to have a glitch that makes it impossible to edit the fields if they already have the desired number of characters.
This is the code I am using currently:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSUInteger newLength = newString.length;
if (textField.tag == 3) {
if (newLength == 4) {
[cellField2 becomeFirstResponder];
}
}
if (textField.tag == 4) {
if (newLength == 4) {
[cellField3 becomeFirstResponder];
}
}
if (textField.tag == 5) {
if (newLength == 5) {
[pinField becomeFirstResponder];
}
}
if (textField.tag == 6) {
if (newLength == 5) {
[pinField resignFirstResponder];
}
}
return YES;
}
I appreciate any help, thanks.
ETA: edited to include danh's code, which I know is more correct than what I was doing. However, my cursor problem remains.
Note that you don't need to use tag's since you have them all in outlets so you could just use: if (textField == cellField1) {, or even better: if (textField == self.cellField1) {. This also makes it easier to follow your code and identify which textField that you are operating on.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSUInteger newLength = newString.length;
if (textField == self.cellField1) {
if (newLength == 3) {
[cellField1 setText:newString];
[cellField2 becomeFirstResponder];
return NO; // NO because we already updated the text.
}
}
if (textField == self.cellField2) {
if (newLength == 3) {
[cellField2 setText:newString];
[cellField3 becomeFirstResponder];
return NO;
}
}
if (textField == self.cellField3) {
if (newLength == 4) {
[cellField3 setText:newString];
[pinField becomeFirstResponder];
return NO;
}
}
if (textField == pinField) {
if (newLength == 5) {
[pinField resignFirstResponder];
return YES;
}
}
return YES;
}
A few things:
newLength needs first to have the the new string, this should solve the counting problem:
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSUInteger newLength = newString.length;
Next, you can just send becomeFirstResponder. No need to send resign since it's implicit in the become.
And this method should answer YES at the end.
lnafziger's answer works great! Those who are finding a swift solution, here is my swift 2.2 code.
func textField(textField: UITextField, shouldChangeCharactersInRangerange: NSRange, replacementString string: String)-> Bool
{
let newString = ((textField.text)! as NSString).stringByReplacingCharactersInRange(range, withString: string)// Convert text into NSString in order to use 'stringByReplacingCharactersInRange' function
let newLength = newString.characters.count // Count the length of 'String' type variable
if (textField == cellField1) {
if (newLength == 3) {
cellField1.text = newString
cellField2.becomeFirstResponder()
return false
}
}
if (textField == cellField2) {
if (newLength == 3) {
cellField2.text = newString
cellField3.becomeFirstResponder()
return false
}
}
if (textField == cellField3) {
if (newLength == 4) {
cellField3.text = newString
pinField.becomeFirstResponder()
return false
}
}
if (textField == pinField) {
if (newLength == 5) {
pinField.resignFirstResponder()
return true
}
}
return true
}

Disabled UIButton dependant on 4 UITextFields

I have 4 UITextFields that I am using to keep 2 UIButtons disabled until all 4 fields have data entered into them. I have the following code so far
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (([brand.text length] >0) && ([qty.text length] >0) && ([size.text length] >0) && ([price.text length] >0)) {
[calcOneButton setEnabled:YES];
[calcTwoButton setEnabled:YES];
}else {
}
}
I have a number of problems with this :-
When data is removed from the fields the UIButtons are still enabled
The Buttons arent enabling correctly, after I have entered data into all 4 fields I need to re-tap on a field to enable the button.
I am logging the length of each field but as a character is entered it starts at a count of 0 not 1.
Can anyone help with these points?
The code for logging the length of a field is as follows :-
#define MAXLENGTH 5
#define MAXQTY 3
#define MAXSIZE 4
#define MAXBRAND 10
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (textField == brand) {
int lengtha = [brand.text length] ;
NSLog(#"lenghta = %d",lengtha);
if (lengtha >= MAXBRAND && ![string isEqualToString:#""]) {
brand.text = [brand.text substringToIndex:MAXBRAND];
return NO;
}
it follows the same format for all 4 fields, but as I enter a character the NSlog results as a 0 then 1 for the second character and so on.
Just use another delegate-method.
Either use: textFieldDidEndEditing: like Krypton told you in a comment
or use textField:shouldChangeCharactersInRange:replacementString: for enable/disable directly when typing.
textField:(UITextField*)aTextField shouldChangeCharactersInRange:(NSRange) aRange replacementString:(NSString*)aRepString
{
NSString *newStr = [aTextField.text stringByReplacingCharactersInRange:aRange withString:aRepString];
if([newStr length]>0 && /*otherStringLength > 0*/)
//enable
else
//disable
return YES;
}
But I think the most common way is to use the didEndEditing-method

setting max capacity to a UITextField

hi
i am using a series of textfields in a row in my application and my requirement is the textfield should accept only one character.if a user enters second character no action should be performed.
i implemented the delegate method as below
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string{
if ([cellTextField.text length]>=MAXLENGTH && range.length==0) {
textField.text=[cellTextField.text substringToIndex:MAXLENGTH-1];
return NO;
}
else {
return YES;
}
but my requirement is not being filled using the above code.
my next requirement is if a user continues entering a second character, the character should be placed in the consecutive textField(imagine crossword or scramble application). please help me in both scenarios if possible else solution for first requirement is also thankful.
thank you,
dinakar
The following code solved this for me.
Make sure you check for the "\b" (Backspace escape character) so that the user can still erase.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField.text length] >= MAXLENGTH && ![string isEqualToString:#"\b"])
return NO;
return YES;
}
As far as your second requirement goes it's really not too hard. Just add a few lines of code into the above if-statement:
nextTextField.text = [nextTextField.text stringByAppendingString:string];
This should add whatever text you just typed in to the end of your next text field. You might also want to change the way backspace is handled. Something like:
if ([string isEqualToString:#"\b"])
nextTextField.text = [nextTextField.text substringToIndex:[nextTextField.text length]-1];
Adding that code inside the above if statement as well should allow you to delete the character at the end of the complete string (at the end of the string in the next text field).
EDIT: Here's the code I use to create the field.
titleInput = [[UITextField alloc] initWithFrame:(CGRect){40,145,400,30}];
titleInput.borderStyle = UITextBorderStyleRoundedRect;
titleInput.delegate = self;
[self addSubview:titleInput];
Cheers
if(cellTextField.text.length >= MAXLENGTH)
{
[cellTextField2 becomeFirstResponder]
}
This sets the focus to be the second text field
check in below functions for the number of character in your UITextField;
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
if the number of character in you text field is more than one just return NO;
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(mytextField1 == textField && [mytextField1.text length] >= 1)
{
[mytextField1 becomeFirstResponder];
return NO;
}
else if(mytextField2 == textField && [mytextField2.text length] >= 1)
{
[mytextField3 becomeFirstResponder];
return NO;
}
-------------------------------
-------------------------------
else if(mytextField8 == textField && [mytextField8.text length] >= 1)
{
[mytextField1 becomeFirstResponder];
return NO;
}
return YES;
}