2012-01-26 3 views
2

В моем приложении у меня есть довольно большая форма для заполнения. Сама форма создается с использованием режима таблицы и статических ячеек. Каждая из ячеек содержит метку и текстовое поле. Я хотел добавить панель инструментов над клавиатурой, чтобы включить навигацию между текстовыми полями. Я сделал это, однако он ведет себя очень странно (по крайней мере, я думаю).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]; 
} 

Спасибо!

+0

Вы пробовали прокручивать представление таблицы, чтобы сделать предыдущую ячейку видимой до того, как вы измените первого ответчика. – dasdom

+0

спасибо @dasdom и rob. я должен был упомянуть, что я пытался. проблема в том, что indexPathForCell возвращает null, если ячейка не видна. в моем приложении не каждая строка содержит текстовое поле, поэтому мне нужно отслеживать их позиции в другом месте. он, конечно, работает, хотя и не является идеальным решением, на мой взгляд. – patman

ответ

0

Сначала попробуйте проверить, видна ли строка. Прокрутите строку до видимой, если она отсутствует. Затем установите текстовое поле в качестве первого ответчика.

Смежные вопросы