我有一个非常简单的项目,我想动态过滤 UITableView
中的内容关于 UISegmentedControl
中的按下索引。我将 MVVM 与 RxSwift、Realm 和 RxDataSources 一起使用。所以我的问题是,如果我想更新 UITableView
中的内容我需要创建“特殊”DisposeBag
,仅用于此目的,并且针对 UISegmentedControl
中的每个选择将其归零并再次创建。仅在这种情况下,如果我理解正确的话,订阅会重新更新,并且 UITableView
显示来自 Realm 的新结果。
那么有没有更好的方法来进行这样的操作呢?当我在 UISegmentedControl
中切换选项卡时,无需每次订阅。这是我的代码:
//ViewController
class MyViewController : UIViewController {
//MARK: - Props
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var segmentedControl: UISegmentedControl!
let dataSource = RxTableViewSectionedReloadDataSource<ItemsSection>()
let disposeBag = DisposeBag()
var tableViewBag: DisposeBag!
var viewModel: MyViewModel = MyViewModel()
//MARK: - View lifecycle
override func viewDidLoad() {
super.viewDidLoad()
self.setupRxTableView()
}
//MARK: - Setup observables
fileprivate func setupRxTableView() {
dataSource.configureCell = { ds, tv, ip, item in
let cell = tv.dequeueReusableCell(withIdentifier: "ItemCell") as! ItemTableViewCell
return cell
}
bindDataSource()
segmentedControl.rx.value.asDriver()
.drive(onNext: {[weak self] index in
guard let sSelf = self else { return }
switch index {
case 1:
sSelf.bindDataSource(filter: .active)
case 2:
sSelf.bindDataSource(filter: .groups)
default:
sSelf.bindDataSource()
}
}).disposed(by: disposeBag)
}
private func bindDataSource(filter: Filter = .all) {
tableViewBag = nil
tableViewBag = DisposeBag()
viewModel.populateApplying(filter: filter)
}).bind(to: self.tableView.rx.items(dataSource: dataSource))
.disposed(by: tableViewBag)
}
}
//ViewModel
class MyViewModel {
func populateApplying(filter: Filter) -> Observable<[ItemsSection]> {
return Observable.create { [weak self] observable -> Disposable in
guard let sSelf = self else { return Disposables.create() }
let realm = try! Realm()
var items = realm.objects(Item.self).sorted(byKeyPath: "date", ascending: false)
if let predicate = filter.makePredicate() { items = items.filter(predicate) }
let section = [ItemsSection(model: "", items: Array(items))]
observable.onNext(section)
sSelf.itemsToken = items.addNotificationBlock { changes in
switch changes {
case .update(_, _, _, _):
let section = [ItemsSection(model: "", items: Array(items))]
observable.onNext(section)
default: break
}
}
return Disposables.create()
}
}
}
最佳答案
不记得这是否让我对 MVVM 失去了兴趣,但是 Variable 不是您正在寻找的东西吗?
Variable<[TableData]> data = new Variable<[TableData]>([])
func applyFilter(filter: Predicate){
data.value = items.filter(predicate) //Any change to to the value will cause the table to reload
}
以及 viewController 中的某处
viewModel.data.rx.asDriver().drive
(tableView.rx.items(cellIdentifier: "ItemCell", cellType: ItemTableViewCell.self))
{ row, data, cell in
//initialize cells with data
}
关于ios - 使用 RxSwift 和 Realm 动态过滤结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46482491/