Панель навигации. Большие заголовки сокращаются, если данные загружаются за пределы экрана через привязку источника данных Rx.

При использовании больших заголовков на панели навигации вместе с UITableView, привязанным к источнику данных драйвера Rx, я заметил, что если привязка и начальная загрузка данных происходят, когда представление находится за пределами экрана, при переходе к этому представлению оно будет прокручиваться. таким образом, что большой заголовок сжимается до «свернутого» положения.

Общая настройка представляет собой UITableViewController с набором prefersLargeTitles = true. Tableview настроен и впоследствии привязан к источнику данных Rx в пределах viewDidLoad.

Пример кода:

override func viewDidLoad() {
  super.viewDidLoad()
  setupTableView()
  bindToTableView()

  // ...
}

private func setupTableView() {
  tableView.register(cellType: Cell.self)
  tableView.tableFooterView = UIView()
  tableView.separatorStyle = .none

  // ...

  // We are required to first reset the data source and delegate to allow
  // for RxCocoa to take over control.
  tableView.dataSource = nil
  tableView.delegate = nil
  tableView.rx.setDelegate(self)
    .disposed(by: bag)

  // ...
}

private func bindToModel() {
  viewModel.modelDriver
    .drive(tableView.rx.items) { tableView, row, model in
      let indexPath = IndexPath(row: row, section: 0)
      let cell: Cell = tableView.dequeueReusableCell(for: indexPath)
      cell.prepare(with: model)
      return cell
    }.disposed(by: bag)
}

И под «сжатым» я подразумеваю, что заголовки переключаются на этот стиль:

маленький заголовок навигации

Кто-нибудь еще сталкивался с этой проблемой?


Решено: как @daniel-t упоминает ниже, проблема вызвана не конкретно Rx, а временем, когда prefersLargeTitles = true. Если это свойство не установлено до вызова tableView.reloadData(), таблица будет загружаться в данные и соответствующим образом прокручиваться для небольших заголовков. Затем, после установки больших заголовков, представление таблицы не сбрасывает положение прокрутки, чтобы компенсировать новую, большую область панели навигации.

Причина, по которой это проявляется несколько странно, даже при использовании чего-то вроде .skipUntil(...viewWillAppear), заключается в том, что акт привязки запускает начальное обновление Rx, которое перезагружает представление таблицы.


person Alex Persian    schedule 19.03.2019    source источник
comment
такая же проблема... есть решение?   -  person Stefan    schedule 03.10.2020


Ответы (1)


Ваша проблема в другом, а не в коде, который вы представили, или в чем-то, что связано с Rx. Следующее работает по назначению:

class ViewController: UITableViewController {

    private let bag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        title = "Title"
        navigationController?.navigationBar.prefersLargeTitles = true

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        tableView.tableFooterView = UIView()
        tableView.separatorStyle = .none
        tableView.dataSource = nil
        tableView.delegate = nil
        tableView.rx.setDelegate(self)
            .disposed(by: bag)

        let modelDriver = Driver.just(Array<String>(repeating: "Hello world", count: 30))
        modelDriver
            .drive(tableView.rx.items) { tableView, row, model in
                let indexPath = IndexPath(row: row, section: 0)
                let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
                cell.textLabel?.text = model
                return cell
            }
            .disposed(by: bag)
    }
}

Может быть, проблема связана с тем, как вы строите свои клетки? Или, может быть, вы где-то прокручиваете список до конца?

person Daniel T.    schedule 20.03.2019