2

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;

}
ElGavilan
  • 6,610
  • 16
  • 27
  • 36
Jim Clermonts
  • 1,694
  • 8
  • 39
  • 94

3 Answers3

2

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.

lucianomarisi
  • 1,552
  • 11
  • 24
1

You are set the Value before the shouldChangeCharactersInRange delegate get its action.

Mean, you need to remove the setText.

Kumar KL
  • 15,315
  • 9
  • 38
  • 60
0

Remove your - setText: methods and do it like this

Create a local variable to keep the reference of the last NSString and the current UITextField

[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(giveText:) userInfo:nil repeats:NO]; // instead of your - setText:

- (void)giveText:(id)sender {

    // set your text here lets say

    [currentTextField setText:lastString];
}

you have to set the text after the return statement, but its impossible so your abusing NSTimer to do that.

Example:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    _lastString = string;
    _currentTextField = textField;

    if(firstCodeField == textField){

        // [firstCodeField setText:newString];

        [secondCodeField becomeFirstResponder];
    }

    // ...... other ifs

    [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(giveText:) userInfo:nil repeats:NO];
}
Goppinath
  • 10,569
  • 4
  • 22
  • 45