Reputation: 2524
Through the awesome help of people on this board I am almost done my app for my students! I was able to make a toolbar appear over the keyboard that has a previous and next buttons. I then made the buttons go between three input fields.
If the user starts in the first field they can go back and forth between all the fields, just like I thought you would if they use the prev/next buttons. However, if the user was on text field three and then clicks on the first field, the buttons stay as they were and then don't work right.
-(void)keyboardWillShow:(id)sender{
if ([inputA isFirstResponder]) {
[nextButton setEnabled:YES];
[previousButton setEnabled:NO];
} else if ([inputB isFirstResponder]) {
[nextButton setEnabled:YES];
[previousButton setEnabled:YES];
} else if ([inputC isFirstResponder]) {
[nextButton setEnabled:NO];
[previousButton setEnabled:YES];
}
}
... cycles through the next text fields
-(void)nextField:(id)sender{
if ([inputA isFirstResponder]) {
[inputB becomeFirstResponder];
[previousButton setEnabled:YES];
[nextButton setEnabled:YES];
} else if ([inputB isFirstResponder]) {
[inputC becomeFirstResponder];
[previousButton setEnabled:YES];
[nextButton setEnabled:NO];
} else if ([inputC isFirstResponder]) {
[inputB becomeFirstResponder];
[previousButton setEnabled:YES];
[nextButton setEnabled:YES];
}
}
... cycles through previous text fields
-(void)previousField:(id)sender{
if ([inputC isFirstResponder]) {
[inputB becomeFirstResponder];
[nextButton setEnabled:YES];
[previousButton setEnabled:YES];
} else if ([inputB isFirstResponder]) {
[inputA becomeFirstResponder];
[nextButton setEnabled:YES];
[previousButton setEnabled:NO];
} else if ([inputA isFirstResponder]) {
[inputB becomeFirstResponder];
[nextButton setEnabled:YES];
[previousButton setEnabled:YES];
}
}
In my keyboard code, the previous button calls previousField, and the next button calls nextField. I figured that when I did the keyboardWillShow, I was setting the different inputs as first responder, but that is only on the first run through.
Is there a way to make it so when the user clicks on the field it becomes the first responder?
Upvotes: 2
Views: 221
Reputation: 183
As for triggering the updating, UITextField
has a delegate method -textFieldDidBeginEditing:
, which you could use to call -setPrevNextButtons
as proposed by @mackworth. Several other methods exist that do similar things—see the related delegate protocol for more information.
For instance, try this controlling code in the text field's delegate:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField == inputA || textField == inputB || textField == inputC)
[self setPrevNextButtons];
}
It should go without saying that you'll have to set the delegate for the text fields for this to work.
Upvotes: 1
Reputation: 5953
Two things I can suggest: first, do it DRY: "Don't Repeat Yourself". Anytime you see the same code over and over, move it to a method. Secondly you didn't specify who calls keyboardWillShow. Check in your nib that it is being called by each inputX upon EditingDidBegin. So the shorter code would be:
-(void) setPrevNextButtons { //ensures that Prev/Next buttons are correct for current firstResponder
if ([inputA isFirstResponder]) {
[nextButton setEnabled:YES];
[previousButton setEnabled:NO];
} else if ([inputB isFirstResponder]) {
[nextButton setEnabled:YES];
[previousButton setEnabled:YES];
} else if ([inputC isFirstResponder]) {
[nextButton setEnabled:NO];
[previousButton setEnabled:YES];
}
}
-(void)keyboardWillShow:(id)sender{
[self setPrevNextButtons];
}
//goes through the different text fields
-(void)nextField:(id)sender{
if ([inputA isFirstResponder]) {
[inputB becomeFirstResponder];
}else if ([inputB isFirstResponder]) {
[inputC becomeFirstResponder];
}
[self setPrevNextButtons];
}
-(void)previousField:(id)sender{
if ([inputC isFirstResponder]) {
[inputB becomeFirstResponder];
} else if ([inputB isFirstResponder]) {
[inputA becomeFirstResponder];
}
[self setPrevNextButtons];
}
If you felt like being tricky, you could also do this:
-(void) setPrevNextButtons {
[previousButton setEnabled: [inputB isFirstResponder] ||
[inputC isFirstResponder] ];
[nextButton setEnabled: [inputA isFirstResponder] ||
[inputB isFirstResponder] ];
}
Upvotes: 0