ios - 在 tableview rx 数据源中拉动以刷新
<p><p>在我的移动应用程序中,我想通过拉取刷新请求来更新 tableView 数据源,但我不知道如何在 tableview 数据源顶部插入新项目。 </p>
<p>我看到有一个 insertRows 的方法,例如:self.tableView?.insertRows(at: , with: .top) 但是如何根据我的方法在此处添加 newItems? </p>
<p>我有一个名为 initializedTableView() 的函数,它使用 PublishSubject 可观察项初始化 tableView。</p>
<pre><code>func initializeTableView() {
viewModel
.items
.subscribe(onNext: { items in
self.tableView?.delegate = nil
self.tableView?.dataSource = nil
Observable.just(items)
.bind(to:(self.tableView?.rx.items(cellIdentifier:
itemCell.Identifier, cellType: itemCell.self))!) {
(index, element, cell) in
cell.itemModel = element
}.disposed(by: self.disposeBag)
})
.disposed(by: disposeBag)
}
</code></pre>
<p>一旦用户请求拉动刷新,就会调用此函数:</p>
<pre><code>func refreshTableView() {
// get new items
viewModel
.newItems
.subscribe(onNext: { newItems in
//new
let new = newItems.filter({ item in
// items.new == true
})
//old
var old = newItems.filter({ item -> Bool in
// items.new == false
})
new.forEach({item in
// how to update tableView.rx.datasource here???
})
}).disposed(by: disposeBag)
}
</code></pre></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><pre><code>struct ViewModel {
let items: BehaviorRelay<>
init() {
self.items = BehaviorRelay(value: [])
}
func fetchNewItems() {
// This assumes you are properly distinguishing which items are new
// and `newItems` does not contain existing items
let newItems: = /* However you get new items */
// Get a copy of the current items
var updatedItems = self.items.value
// Insert new items at the beginning of currentItems
updatedItems.insert(contentsOf: newItems, at: 0)
// For simplicity this answer assumes you are using a single cell and are okay with a reload
// rather than the insert animations.
// This will reload your tableView since 'items' is bound to the tableView items
//
// Alternatively, you could use RxDataSources and use the `RxTableViewSectionedAnimatedDataSource`
// This will require a section model that conforms to `AnimatableSectionModelType` and some
// overall reworking of this example
items.accept(updatedItems)
}
}
final class CustomViewController: UIViewController {
deinit {
disposeBag = DisposeBag()
}
@IBOutlet weak var tableView: UITableView!
private var disposeBag = DisposeBag()
private let viewModel = ViewModel()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CustomTableCell.self, forCellReuseIdentifier: "ReuseID")
tableView.refreshControl = UIRefreshControl()
viewModel.items
.bind(to: tableView.rx.items(cellIdentifier: "ReuseID", cellType: CustomTableCell.self)) { row, item, cell in
// Configure cell with item
cell.configure(with: item)
}
.disposed(by: disposeBag)
tableView.refreshControl?.rx.controlEvent(.valueChanged)
.subscribe(onNext: { in
self?.viewModel.fetchNewItems()
})
.disposed(by: disposeBag)
}
}
</code></pre>
<p>使用 <code>BehaviorRelay</code> 和绑定(bind)的替代答案。这样,您只需更新 <code>items</code> 中继,它会自动更新 tableView。它还提供了一种更“Rx”的方式来处理拉取刷新。</p>
<p>如代码注释中所述,这假设您正在确定哪些项目是新的,并且 <code>newItems</code> 不包含任何现有项目。无论哪种方式,这都应该提供一个起点。</p></p>
<p style="font-size: 20px;">关于ios - 在 tableview rx 数据源中拉动以刷新,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/53518117/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/53518117/
</a>
</p>
页:
[1]