I’m using the following code to move to the next field using the UITextField delegate and also I’m adding a toolbar to the keyboard with the previous, next and ok buttons. The code is working fine.
Like you see the keyboard return button logic is pretty generic, using the UITextField tags, and that’s good because I’m gonna use the piece of code all around. Now I will need to write the previous and next buttons logic, and I’m lost. Any ideas?
UPDATE (complete code, with some modifications, thanks to @8vius that spent some time with me in the chat to make it work):
//
// SigninViewController.m
//
#import "SigninViewController.h"
@implementation SigninViewController
@synthesize firstResponder = _firstResponder;
@synthesize toolbar;
@synthesize email;
@synthesize password;
- (void)move:(UIBarButtonItem*)sender {
NSInteger tag = self.firstResponder.tag;
if ([sender.title isEqualToString:@"Anterior"]) {
tag -= 1;
} else if ([sender.title isEqualToString:@"Próximo"]) {
tag += 1;
}
UITextField *nextTextField = (UITextField*)[self.view viewWithTag:tag];
if (nextTextField && tag > 0) {
[nextTextField becomeFirstResponder];
} else {
[self.firstResponder resignFirstResponder];
self.firstResponder = nil;
}
}
- (void)ok:(id)sender {
[self.view endEditing:YES];
self.firstResponder = nil;
}
- (void)textFieldDidBeginEditing:(UITextField*)textField {
self.firstResponder = textField;
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
NSInteger tag = textField.tag + 1;
UITextField *nextTextField = (UITextField*)[self.view viewWithTag:tag];
if (nextTextField) {
[nextTextField becomeFirstResponder];
} else {
[textField resignFirstResponder];
self.firstResponder = nil;
}
return NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.email.delegate = self;
self.password.delegate = self;
if (self.toolbar == nil)
{
self.toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
UIBarButtonItem* previous = [[UIBarButtonItem alloc] initWithTitle:@"Anterior" style:UIBarButtonItemStyleBordered target:self action:@selector(move:)];
UIBarButtonItem* next = [[UIBarButtonItem alloc] initWithTitle:@"Próximo" style:UIBarButtonItemStyleBordered target:self action:@selector(move:)];
UIBarButtonItem* space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:(UIBarButtonSystemItemFlexibleSpace) target:nil action:nil];
UIBarButtonItem* ok = [[UIBarButtonItem alloc] initWithTitle:@"Ok" style:UIBarButtonItemStyleBordered target:self action:@selector(ok:)];
[self.toolbar setItems:[[NSArray alloc] initWithObjects:previous, next, space, ok, nil]];
[self.toolbar setTranslucent:YES];
[self.toolbar setTintColor:[UIColor blackColor]];
}
for (UIView* view in self.view.subviews) {
if ([view isKindOfClass:[UITextField class]]) {
[(UITextField*)view setInputAccessoryView:toolbar];
}
}
}
- (void)viewDidUnload {
self.email = nil;
self.password = nil;
[super viewDidUnload];
}
@end
It’s quite simple, when you load your view you set the
tagproperty on your text fields depending on the order you want them in, then you have to just traverse the tag element on the fields:And keep track of who is the first responder:
And when you load your view, you bind the buttons to the toggle action:
In my case, for instance, I set up my text fields inside a table view, so in my
cellForRowAtIndexPathmethod I set thetagproperty to be therowof theindexPath.EDIT: You have to set the
firstResponderproperty for it to work.In your .h file:
In your .m file: