ios - 使用 RxSwift 和 Realm 动态过滤结果

标签 ios swift realm rx-swift rxdatasources

我有一个非常简单的项目,我想动态过滤 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/

相关文章:

ios - 宽度约束更新后 View 未重绘

swift - 转换一个快速字典([String :AnyObject] ) to a UnsafeMutablePointer

java - Realm 中的线程 - 干净的代码架构

swift - 每个场景的工具栏按钮

android - 如何删除 Realm 数据库中的 Realm 列表

android - 使用 Android Realm 存储 LatLng

ios - SceneKit通过特定索引有选择地为面部着色

ios - 将 id 转换为长类型崩溃

ios - 等同于 CGRectIntersectsRect

ios - 在解除分配其实例时是否必须将委托(delegate)设置为 nil 并且它被引用到自身?