Как остановить UITableView.reloadData () мешать настройке UITableView.contentOffset - PullRequest
1 голос
/ 02 марта 2020

A UIViewController содержит UITableView. Как только V C станет видимым, мне нужно позвонить UITableView.reloadData(), чтобы убедиться, что данные таблицы синхронизируются с c с моей моделью. В то же время я хотел бы использовать `UITableView.contenOffset = xy", чтобы прокрутить TableView, чтобы показать определенные c данные, когда они становятся видимыми.

Хотя это работает в тех же случаях, большую часть времени это не работает одновременно . Кажется, что UITableView.reloadData() пытается сохранить текущую позицию прокрутки и таким образом мешает прокрутке вручную, используя UITableView.contenOffset.

Как решить эту проблему?


Подробности:

  • Контроллер родительского представления представляет один из двух возможных контроллеров дочернего представления.
    • Один дочерний контроллер представления является просмотрщиком который показывает данные некоторой сущности, например, данные сотрудника, такие как имя, адрес, номера телефонов и т. д. c.
    • Другой дочерний контроллер представления - это редактор , который позволяет обновлять сведения об объекте emplyee.
    • Оба контроллера дочерних представлений используют UITableView для представления данных
  • Предположим, что TableView на ViewVC в настоящее время прокручивается до адрес раздел.
  • При переключении в режим редактирования EditVC необходимо обновить свой TableView, чтобы отобразить выбранное в настоящее время занятое. Кроме того, TableView в EditVC также необходимо прокрутить, чтобы показать раздел address .

Код:

var scrollOnViewWillAppear = false;

override func willMove(toParent parent: UIViewController?) {
    super.willMove(toParent: parent)
    employee = loadData

    if (isViewLoaded) {
        tableView.reloadData()
        tableView.contentOffset = getOffsetShowingTheSameDataAsInViewerVC()

        // Result is the same when using scrollRectToVisible as proposend in the comments 
        // tableView.scrollRectToVisible(CGRect(x: 0, y: getOffsetShowingTheSameDataAsInViewerVC(), width: tableView.frame.size.width, height: tableView.frame.size.height), animated: false)
    } else {
        scrollOnViewWillAppear = true
    }
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)

    if (scrollOnViewWillAppear) {
        tableView.contentOffset = getOffsetShowingTheSameDataAsInViewerVC()
    }
}

Как описано, это не работает, поскольку перезагрузка перекрывается с ручной прокруткой.

Задержка прокрутки с помощью DispatchQueue.main.async не решает проблему. Кроме того, при использовании этой задержки в viewWillAppear UITableView ненадолго появляется со старым положением прокрутки и обновляется ли это до нового смещения содержимого. Это выглядит плохо.

Я нашел другие посты, в которых предлагалось использовать tableView.layer.removeAllAnimations() сразу после tableView.reloadData(), чтобы запретить TableView выполнять свои собственные действия прокрутки для сохранения того же смещения содержимого.

Итак: Как решить эту проблему?


Мне нужно что-то вроде этого:

  • Перезагрузите TableView в EditVC до того, как V C станет видимым
  • Подождите, пока TableView перезагрузит данные (и сохранит позицию прокрутки)
  • Обновите позицию прокрутки вручную, все еще до V C стал видимым
  • Пусть V C станет видимым, чтобы показать TableView пользователю, прокручиваемому в правильную позицию.

1 Ответ

0 голосов
/ 03 марта 2020

Вы можете подождать, пока не закончится tableView.reloadData(), и установить смещение контента после этого:

tableView.reloadData {
    self.tableView.contentOffset = getOffsetShowingTheSameDataAsInViewerVC()
}

extension UITableView {
    func reloadData(completion: @escaping () -> Void) {
        UIView.animate(withDuration: 0, animations: {
            self.reloadData()
        }, completion: { _ in
            completion()
        })
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...