如果通过 Rx 数据源绑定加载数据 off-screen,导航栏大标题会缩小
Navigation bar Large Titles are shrunk if data is loaded off-screen through an Rx datasource binding
当在导航栏中使用大标题以及绑定到 Rx driver 数据源的 UITableView 时,我注意到如果绑定和初始数据加载发生在视图处于屏幕外时,当您导航到该视图,它将滚动,以便大标题缩小到“最小化”位置。
总体设置是一个设置了 prefersLargeTitles = true
的 UITableViewController。 Tableview 已设置并随后绑定到 viewDidLoad
.
中的 Rx 数据源
示例代码:
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)
}
"shrunk" 我的意思是标题切换到这种风格:
还有其他人遇到过这个问题吗?
已解决: 正如@daniel-t 在下面提到的,问题不是由 Rx 具体引起的,而是由 prefersLargeTitles = true
的时间引起的。如果在 调用 tableView.reloadData()
之前 未设置此 属性,则 table 将加载数据并适当滚动 non-large 个标题。然后在设置大标题后,table视图不会重置它的滚动位置以补偿新的、更大的导航栏区域。
即使在使用 .skipUntil(...viewWillAppear)
之类的东西时,这种表现也有些奇怪的原因是因为绑定操作会触发初始 Rx 更新,从而重新加载 table 视图。
您的问题出在别处,不在您提供的代码中,也不在与 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)
}
}
也许问题与您构建细胞的方式有关?或者,也许您正在滚动到列表底部的某处?
当在导航栏中使用大标题以及绑定到 Rx driver 数据源的 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)
}
"shrunk" 我的意思是标题切换到这种风格:
还有其他人遇到过这个问题吗?
已解决: 正如@daniel-t 在下面提到的,问题不是由 Rx 具体引起的,而是由 prefersLargeTitles = true
的时间引起的。如果在 调用 tableView.reloadData()
之前 未设置此 属性,则 table 将加载数据并适当滚动 non-large 个标题。然后在设置大标题后,table视图不会重置它的滚动位置以补偿新的、更大的导航栏区域。
即使在使用 .skipUntil(...viewWillAppear)
之类的东西时,这种表现也有些奇怪的原因是因为绑定操作会触发初始 Rx 更新,从而重新加载 table 视图。
您的问题出在别处,不在您提供的代码中,也不在与 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)
}
}
也许问题与您构建细胞的方式有关?或者,也许您正在滚动到列表底部的某处?