В моем приложении у меня есть довольно большая форма для заполнения. Сама форма сделана с табличным представлением и режимом статических ячеек. Каждая из ячеек содержит метку и текстовое поле. Я хотел добавить панель инструментов над клавиатурой, чтобы включить навигацию между текстовыми полями. Я так и сделал, однако ведет себя очень странно (по крайней мере, я так думаю).
У меня нет проблем с переходом к следующему текстовому полю, а переход к предыдущему текстовому полю возможен только в том случае, если он виден. Если оно не видно, старое текстовое поле остается первым респондентом, однако, как только я прокручиваю свое табличное представление и предполагаемое текстовое поле становится видимым, оно становится первым респондентом (я не нажимаю на него!) Ну, это, конечно, не то поведение, которое я хотел.
Мой вопрос: нормально ли такое поведение? Не могли бы вы как-нибудь обойти это?
Если вы хотите увидеть подобное поведение самостоятельно, я загрузил проект Xcode, который иллюстрирует проблему. Вы можете скачать сжатый проект здесь: download . Основные части кода описаны ниже.
Я настроил сгруппированное табличное представление со статической ячейкой. Каждый из них содержит ярлык и textfield
. Я создал точки для каждого текстового поля, чтобы получить к ним доступ. В моем методе viewDidLoad я создаю панель инструментов и ее кнопки, сохраняю текстовые поля в массиве и устанавливаю контроллер в качестве делегата текстовых полей.
- (void)viewDidLoad
{
[super viewDidLoad];
// create the keyboard toolbar with navigation elements
self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
UIBarButtonItem *prevButton = [[UIBarButtonItem alloc] initWithTitle:@"Previous" style:UIBarButtonItemStyleBordered target:self action:@selector(prevClicked:)];
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:@"Next" style:UIBarButtonItemStyleBordered target:self action:@selector(nextClicked:)];
[self.keyboardToolbar setItems:[NSArray arrayWithObjects:prevButton, nextButton, nil]];
// create the field chain
self.fields = [NSArray arrayWithObjects:self.aField, self.bField, self.cField, self.dField, self.eField, self.fField, nil];
// for scrolling and keeping track of currently active field
NSInteger max = [self.fields count];
for(NSInteger i = 0; i < max; i++) {
UITextField *curr = (UITextField *)[self.fields objectAtIndex:i];
curr.delegate = self;
}
}
Методы делегата текстового поля хранят ссылку на активное текстовое поле и предотвращают вставку разрывов строк.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
textField.inputAccessoryView = self.keyboardToolbar;
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
// set the current active textfield
self.currentField = textField;
// scroll this textfield to top
UITableViewCell *cell = (UITableViewCell *)textField.superview.superview;
[self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
self.currentField = nil;
return NO;
}
И, наконец, есть селекторы для кнопок панели инструментов и логика для получения следующего текстового поля.
- (void)moveResponderByStep:(NSInteger)step
{
// only move if a textfield is the current responder
if(![self.currentField isEditing]) {
return;
}
// where we are and where to move
NSInteger max = [self.fields count];
NSInteger moveToNumber;
for(NSInteger i = 0; i < max; i++) {
if(self.currentField == [self.fields objectAtIndex:i]) {
moveToNumber = i + step;
}
}
// stay in bounds
if(moveToNumber >= max || moveToNumber < 0) {
[self.currentField resignFirstResponder];
return;
}
// move on
UITextField *next = [self.fields objectAtIndex:moveToNumber];
[next becomeFirstResponder];
}
- (void)prevClicked:(id)sender
{
[self moveResponderByStep:-1];
}
- (void)nextClicked:(id)sender
{
[self moveResponderByStep:1];
}
Спасибо!