UITableView scrollToRowAtIndexPath прокручивается только иногда

#iphone #objective-c #cocoa-touch #uitableview

#iPhone #objective-c #cocoa-touch #uitableview

Вопрос:

У меня есть UITableView с несколькими UITableViewCells, а внутри этих ячеек находятся UITextFields. Я реализовал UIToolbar для переключения между различными текстовыми полями. Я могу перейти к следующему текстовому полю в следующей ячейке или к предыдущему текстовому полю. Это работает нормально, пока ячейка не станет первым ответчиком, который в настоящее время не отображается в tableview.

Я понял, что

 [self.tableview cellForRowAtIndexPath:indexPath]
  

возвращает nil и то, что ручная прокрутка до ячейки с текстовым полем, которое должно стать первым ответчиком, устраняет проблему. Поэтому я попытался прокрутить ячейку, прежде чем изменять ее, чтобы стать первым ответчиком.

Я пробовал это с

 [[self.tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
  

но, к сожалению, tableview прокручивается не до этой ячейки, а до всех других ячеек. Когда я добавляю точку останова в эту строку, проблема не возникает. Также похоже, что tableview прокручивается до ячейки, но затем снова прокручивается вниз.

Вот код cellForRowAtIndexPath:

 UITableViewCell *cell;
static NSString *AttributeCellIdentifier = @"AttributeCellIdentifier";
    cell = [tableView dequeueReusableCellWithIdentifier:AttributeCellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"AttributeCell" owner:self options:nil];
        cell = attributeCell;
        self.attributeCell = nil;
        UITextField * textField = (UITextField *)[cell viewWithTag:1];
        [textField setKeyboardType:UIKeyboardTypeDecimalPad];
        [textField setInputAccessoryView:[self inputAccessoryView]];
    }
UITextField * textField;
textField = (UITextField *)[cell viewWithTag:1];
textField.placeholder = @"C(Probe)/mol/l";
return cell;
  

Вот код для переключения на предыдущее текстовое поле:

 UIView * currentResponder = [self.view findFirstResonder];

UITextField * newFocusTextField;
UITableViewCell * cell = (UITableViewCell*)[[currentResponder superview] superview];
NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];

newFocusTextField = (UITextField*)[[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]] viewWithTag:1];
[currentResponder resignFirstResponder];
[newFocusTextField becomeFirstResponder];

UITableViewCell * newCell = (UITableViewCell*)[[newFocusTextField superview] superview];
NSIndexPath * newIndexPath = [self.tableView indexPathForCell:newCell];
[self.tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
  

Надеюсь, это поможет.

Комментарии:

1. Пожалуйста, опубликуйте код для cellForRowAtIndexPath. Вы написали содержимое этого метода? Если да, то почему он возвращает nil? Если нет, то почему бы и нет?

2. Я написал этот код, и я думаю, что он возвращает nil, потому что ячейка не видна, когда прокрутка не работает. Из документации для cellForRowAtIndexPath: объект, представляющий ячейку таблицы или nil, если ячейка не видна или indexPath находится вне диапазона.

3. Как это достигается, когда вы нажимаете на панель инструментов, чтобы открыть / отредактировать текстовое поле? Мне интересно, есть ли здесь проблема с упорядочением, т. Е. вам может потребоваться прокрутить таблицу, чтобы сначала отобразить ячейку, а затем сделать ее первым ответчиком.

4. @Mike — Я понимаю вашу точку зрения, и я попробовал это, но это не решает проблему.

Ответ №1:

Код в вашем сообщении и определение проблемы не на сто процентов понятны, но была ошибка / глюк в методах прокрутки, работающих для iOS 3.0 (я думаю, конкретно 3.0, насколько я помню). Я не мог понять причину, по которой это произошло, но все время происходил сбой, хотя для iOS 4.x это было нормально.

Исправление заключалось в добавлении

 [table reloadData] 
  

перед строкой прокрутки. Я знаю, что это не имеет смысла, и я знаю, что это не очень хорошая практика, особенно если рендеринг ячейки дорогой, но в этом случае это решило проблему. Я не знаю, связана ли ваша проблема с той же проблемой, но вы можете просто попробовать…

Комментарии:

1. Боюсь, но это не решает мою проблему. Я отредактирую свой запрос, чтобы более четко объяснить свою проблему.

Ответ №2:

Я попробовал несколько попыток, и теперь все работает нормально. Я удалил:

 [currentResponder resignFirstResponder];
  

И после удаления этой строки tableview прокручивается нормально, и я могу напрямую установить указатель на новую ячейку с помощью newFocusTextField и сделать его firstResponder с помощью:

 [newFocusTextField becomeFirstResponder];
  

У меня есть метод nextTextField, который отлично работает с

 [currentResponder resignFirstResponder];
  

итак, я не совсем понимаю, почему возникает проблема, но я думаю, что прокрутка до ячейки, а затем просто установка нового firstResponder лучше, чем сначала отменить currentResponder.

В любом случае спасибо за помощь 😉