ScrollToRowAtIndexPath не обрабатывает последнюю строку правильно

У меня проблема с UITableView, где, похоже, не работает с прокруткой до последней строки при использовании scrollToRowAtIndexPath:atScrollPosition:animated

Вот код, который я использую, чтобы вызвать свиток:

[self.tableView scrollToRowAtIndexPath:indexPath
                      atScrollPosition:UITableViewScrollPositionMiddle 
                              animated:YES];

И вот скриншот, показывающий результат (и вопрос!):

UITableView scroll issue screenshot

Как вы можете видеть, самая последняя строка (сентябрь) полностью не прокручивается; нижние несколько пикселей отключены.

Я пробовал использовать UITableViewScrollPositionNone, UITableViewScrollPositionTop и UITableViewScrollPositionBottom как позицию прокрутки, но все они дают одинаковый результат.

Моя ячейка имеет пользовательскую высоту ячейки 61.0f, которая в настоящее время установлена ​​в раскадровке, но добавление метода UITableViewDelegate tableView:heightForRowAtIndexPath: и возврат того же значения не помогает.

Есть ли способ получить представление таблицы для прокрутки до последней строки И, чтобы она полностью видела?

EDIT:

Чтобы быть ясным, я использую запас UINavigationController с запасом UITableViewController в качестве его контроллера корневого представления.

ИЗМЕНИТЬ 2:

Если я использую rectForRowAtIndexPath:, чтобы определить прямоугольник для строки, он фактически возвращает правильный прямоугольник для этой строки. Но если я тогда вызову scrollRectToVisible:animated:, используя этот rect, я получаю тот же результат, что и выше; нижние несколько пикселей отключены.

Ответы

Ответ 1

Хорошо, я успешно смог исправить эту проблему.

Ключ был в этом comment от Matt Di Pasquale по частично связанному вопросу.

Оказывается, что в iOS 7 представления еще не выложены, когда вызывается viewWillAppear:, что означает, что кадр и границы представления таблицы не гарантируются. Поскольку вызов scrollToRowAtIndexPath:animated должен использовать хотя бы один из них для вычисления смещения, это имеет смысл, почему в моем случае он не обрабатывался должным образом.

Я думаю, что в большинстве случаев люди не будут сталкиваться с этой проблемой, поскольку их предстающий контроллер представления, вероятно, будет иметь те же границы, что и представленный контроллер представления. Но в моем случае я представлял контроллер представления, у которого была видимая панель навигации и строка состояния от той, у которой ее тоже не было, ergo было дополнительное 64pts для учетной записи. Как видно на этом выходе консоли:

2014-03-15 19:14:32.129 Capture[3375:60b] viewWillAppear, tv bounds: {{0, 0}, {320, 568}}
2014-03-15 19:14:32.131 Capture[3375:60b] viewDidLayoutSubviews, tv bounds: {{0, -64}, {320, 568}}

Чтобы обойти проблему, теперь я устанавливаю флаг в viewWillAppear:, который означает наличие ожидающего прокрутки, а затем в viewDidLayoutSubviews, если флаг установлен, я вызываю scrollToRowAtIndexPath:animated и отменяет флаг (поскольку этот метод называется неоднократно). Это работает безупречно.

Надеюсь, это поможет кому-то еще решить эту проблему.

Ответ 2

Как использовать функцию нижнего уровня? В конце концов, a UITableView является UIScrollView.

[self.tableView setContentOffset:(CGPoint){0, self.tableView.contentSize.height - self.tableView.bounds.size.height} animated:YES];

(Отрегулируйте смещение по желанию, если у вас есть вставки содержимого, отличные от 0).

Ответ 3

Я заметил ту же ошибку, когда я прокручивался до определенной строки tableView, когда пользователь прикасается к кнопке "Назад". Я заметил, что во время навигации contentInset табличного вида меняется (из-за automaticallyAdjustsScrollViewInsets = true). Единственное решение, которое я нашел, это добавить наблюдателя:

tableView.addObserver(self, forKeyPath: "contentInset", options: .new, context: nil)

и выполнить scrollToRow метод после, установленный contentInset. Это не красивое решение, но оно работает.

Ответ 4

Я также предлагаю вам включить свойство UIViewController, которое включено по умолчанию:

@property (nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets;

Это помогло мне со многими проблемами, когда я не знал, почему UITableView (который является подклассом UIScrollView на самом деле) не прокручивался должным образом. В зависимости от вашего оформления, конечно.

Это свойство доступно с iOS 7, подробнее об этом читайте здесь:

http://b2cloud.com.au/general-thoughts/uiviewcontroller-changes-in-ios7