我有一个非常简单的项目,我想在其中动态过滤UITableView
有关UISegmentedControl
. 我将 MVVM 与 RxSwift、Realm 和 RxDataSources 一起使用。所以我的问题是,如果我想更新内容,UITableView
我需要创建 'special' DisposeBag
,仅用于此目的,并且在UISegmentedControl
nil 中的每个选择并再次创建。只有在这种情况下,如果我理解正确,订阅会重新更新,并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()
}
}
}