在我的移动应用程序中,我想通过拉取刷新请求来更新 tableView 数据源,但我不知道如何在 tableview 数据源顶部插入新项目。
我看到有一个 insertRows 的方法,例如:self.tableView?.insertRows(at: [indexPath], with: .top) 但是如何根据我的方法在此处添加 newItems?
我有一个名为 initializedTableView() 的函数,它使用 PublishSubject 可观察项初始化 tableView。
func initializeTableView() {
viewModel
.items
.subscribe(onNext: { items in
self.tableView?.delegate = nil
self.tableView?.dataSource = nil
Observable.just(items)
.bind(toself.tableView?.rx.items(cellIdentifier:
itemCell.Identifier, cellType: itemCell.self))!) {
(index, element, cell) in
cell.itemModel = element
}.disposed(by: self.disposeBag)
})
.disposed(by: disposeBag)
}
一旦用户请求拉动刷新,就会调用此函数:
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)
}
struct ViewModel {
let items: BehaviorRelay<[Item]>
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: [Item] = /* 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: { [weak self] in
self?.viewModel.fetchNewItems()
})
.disposed(by: disposeBag)
}
}
使用 BehaviorRelay
和绑定(bind)的替代答案。这样,您只需更新 items
中继,它会自动更新 tableView。它还提供了一种更“Rx”的方式来处理拉取刷新。
如代码注释中所述,这假设您正在确定哪些项目是新的,并且 newItems
不包含任何现有项目。无论哪种方式,这都应该提供一个起点。
关于ios - 在 tableview rx 数据源中拉动以刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53518117/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |