В моем приложении у меня есть довольно большая форма для заполнения. Сама форма создается с использованием режима таблицы и статических ячеек. Каждая из ячеек содержит метку и текстовое поле. Я хотел добавить панель инструментов над клавиатурой, чтобы включить навигацию между текстовыми полями. Я сделал это, однако он ведет себя очень странно (по крайней мере, я думаю).iOS 5: странное поведение при переходе между текстовыми полями
У меня нет проблем с переходом на следующее текстовое поле, а переход к предыдущему текстовому полю возможен только в том случае, если он виден. Если это не видно, старое текстовое поле остается первым ответчиком, однако в тот момент, когда я просматриваю свой табличный вид и видимое текстовое поле становится видимым, оно становится первым ответчиком (я не нажимаю на него!). Ну, это, конечно, не то поведение, которое я хотел.
Мой вопрос: Является ли такое поведение нормальным? Не могли бы вы как-то обойти это?
Если вы хотите увидеть это поведение самостоятельно, я загрузил проект Xcode, который иллюстрирует проблему. Вы можете скачать zipped проект здесь: 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];
}
Спасибо!
Вы пробовали прокручивать представление таблицы, чтобы сделать предыдущую ячейку видимой до того, как вы измените первого ответчика. – dasdom
спасибо @dasdom и rob. я должен был упомянуть, что я пытался. проблема в том, что indexPathForCell возвращает null, если ячейка не видна. в моем приложении не каждая строка содержит текстовое поле, поэтому мне нужно отслеживать их позиции в другом месте. он, конечно, работает, хотя и не является идеальным решением, на мой взгляд. – patman