Search code examples
iosobjective-cuitextfielduitextviewdelegate

UITextField is not a maximum of 1 number when I combine it with resignFirstResponder


The code that checks if the maximum numbers is 1, works when I only use that piece of code. But when I add the automatic jumping to the next UITextField with [becomFirstResponder], it doesn't work anymore.

Many thanks guys!

enter image description here enter image description here enter image description here

When

MyViewController.h

@interface GateKeeperViewController : UIViewController <UITextFieldDelegate>

@property (strong, nonatomic) IBOutlet UITextField *firstCodeField;
@property (strong, nonatomic) IBOutlet UITextField *secondCodeField;
@property (strong, nonatomic) IBOutlet UITextField *thirdCodeField;
@property (strong, nonatomic) IBOutlet UITextField *fourthCodeField;
@property (strong, nonatomic) IBOutlet UITextField *fifthCodeField;

MyViewController.m

@synthesize firstCodeField;
@synthesize secondCodeField;
@synthesize thirdCodeField;
@synthesize fourthCodeField;
@synthesize fifthCodeField;

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self initFieldListeners];
}

-(void) initFieldListeners {

    firstCodeField.delegate = self;
    secondCodeField.delegate = self;
    thirdCodeField.delegate = self;
    fourthCodeField.delegate = self;
    fifthCodeField.delegate = self;

    [self.firstCodeField addTarget:self
                            action:@selector(textFieldEditing:)
                  forControlEvents:UIControlEventEditingChanged];

    [self.secondCodeField addTarget:self
                             action:@selector(textFieldEditing:)
                   forControlEvents:UIControlEventEditingChanged];

    [self.thirdCodeField addTarget:self
                            action:@selector(textFieldEditing:)
                  forControlEvents:UIControlEventEditingChanged];

    [self.fourthCodeField addTarget:self
                             action:@selector(textFieldEditing:)
                   forControlEvents:UIControlEventEditingChanged];

    [self.fifthCodeField addTarget:self
                            action:@selector(textFieldEditing:)
                  forControlEvents:UIControlEventEditingChanged];
}

- (void)textFieldEditing:(UITextField *)textField
{
    if(textField == self.firstCodeField ){
        if ([self.firstCodeField.text length] == 1) {
            [self.secondCodeField becomeFirstResponder];
        }
    }

    if(textField == self.secondCodeField ){
        if ([self.secondCodeField.text length] == 1) {
            [self.thirdCodeField becomeFirstResponder];
        }
    }

    if(textField == self.thirdCodeField ){
        if ([self.thirdCodeField.text length] == 1) {
            [self.fourthCodeField becomeFirstResponder];
        }
    }

    if(textField == self.fourthCodeField ){
        if ([self.fourthCodeField.text length] == 1) {
            [self.fifthCodeField becomeFirstResponder];
        }
    }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    return (newLength > 1) ? NO : YES;

}

Solution

  • I suggest a slightly different solution, use target-action on the textfield to get notified for editing events. The idea is that your action would get executed after the shouldChangeCharactersInRange method. For example using 3 textfields:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        [self.firstTextField addTarget:self
                                action:@selector(textFieldEditing:)
                      forControlEvents:UIControlEventEditingChanged];
    
        [self.secondTextField addTarget:self
                                 action:@selector(textFieldEditing:)
                       forControlEvents:UIControlEventEditingChanged];
    
    }
    
    - (void)textFieldEditing:(UITextField *)textField
    {
        if(textField == self.firstTextField ){
            if ([self.firstTextField.text length] == 1) {
                [self.secondTextField becomeFirstResponder];
            }
        }
    
        if(textField == self.secondTextField ){
            if ([self.secondTextField.text length] == 1) {
                [self.thirdTextField becomeFirstResponder];
            }
        }
    }
    
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
        NSUInteger newLength = [textField.text length] + [string length] - range.length;
        return (newLength > 1) ? NO : YES;
    
    }
    

    There is still some improvement that can be done on this code but it should get you started.