首页 > 解决方案 > 如果通过 Rx 数据源绑定在屏幕外加载数据,则导航栏大标题会缩小

问题描述

当在导航栏中使用大标题以及绑定到 Rx 驱动程序数据源的 UITableView 时,我注意到如果在视图离开屏幕时发生绑定和初始数据加载,当您导航到该视图时,它将被滚动这样大标题就会缩小到“最小化”的位置。

整体设置是一个带有prefersLargeTitles = true集合的 UITableViewController。Tableview 已设置并随后绑定到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 具体引起的,而是由 when 的时间安排引起的prefersLargeTitles = true。如果在调用之前未设置此属性,tableView.reloadData()则表格将加载数据并为非大标题适当滚动。然后在设置大标题后,tableview 不会重置它的滚动位置以补偿新的更大的导航栏区域。

即使使用类似的东西.skipUntil(...viewWillAppear),这也显得有些奇怪,因为绑定的行为会触发初始 Rx 更新,该更新会重新加载 tableview。

标签: iosswiftrx-swift

解决方案


您的问题出在其他地方,而不是您提供的代码或与 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)
    }
}

也许问题与您如何构建细胞有关?或者,也许您正在某个地方滚动到列表的底部?


推荐阅读