0

在我的视图控制器中,我有一个与 UITableView 关联的 UISearchController。所以我所有的普通表视图数据源方法都是旧的

if isSearching {
    // use filteredTableData array
} else {
    // use SharedModel.shared.participants 
}

我不清楚如何使用 RxCocoa 来实现它,因为我是 Rx 的新手。

4

2 回答 2

1

Variable在下面创建一个

var tableViewOptions = Variable<[String]>([]) // replace String with your own object

在视图加载后绑定tableViewOptions到。tableview

tableViewOptions
  .asObservable()
  .bind(to: self.tableView
    .rx
    .items(cellIdentifier: "cellIdentifier",
           cellType: CustomCell.self)) { _, values, cell in
           // do your stuff
}

然后,当您搜索更改如下值时tableViewOptions

if isSearching {
  tableViewOptions.value = filteredTableArray
} else {
  tableViewOptions.value = SharedModel.shared.participants
}
于 2017-11-29T05:25:12.487 回答
0

我通过为 an 声明一个装饰器Observable并为 a 声明一个扩展来解决这个问题UISearchBar(您也可以为 声明它UISearchController):

//FIXME: Item can't be type constrained. Have to use optional casting.
class FilterableByTitleCollection<Item>: ObservableType {

    private let origin: Observable<Array<Item>>
    private let filteringStrategySource: Observable<TitlableModelFilteringStrategy> //FIXME: This is a strategy source

    init<Origin: ObservableType>(
        origin: Origin,
        filteringStrategySource: Observable<TitlableModelFilteringStrategy>) where Origin.E == Array<Item> {
        self.origin = origin.asObservable()
        self.filteringStrategySource = filteringStrategySource
    }

    typealias E = Array<Item>
    func subscribe<O:ObserverType>(_ observer: O) -> Disposable where O.E == Array<Item> {
        return Observable.combineLatest(
                origin,
                filteringStrategySource
            )
            .observeOn(ConcurrentDispatchQueueScheduler(qos: .userInitiated))
            .map{ origin, strategy in
                guard origin is Array<Titlable> else { assert(false); return origin }
                return origin.filter{ strategy.shouldInclude(item: $0 as! Titlable) }
            }
            .observeOn(MainScheduler.instance)
            .subscribe(observer)
    }

}

...

extension UISearchBar {

    var titlableFilteringStrategy: Observable<TitlableModelFilteringStrategy> {
        return Observable<String?>.merge(
            [
                self.rx.text.asObservable(),
                self.rx.textDidEndEditing
                    .map{ [weak self] in
                        assert(self != nil)
                        return self?.text
                    },
                self.rx.cancelButtonClicked.map{ Optional<String>.some("") }
            ]
        ).distinctUntilChanged{ (old: String?, new: String?) -> Bool in
            old == new
        }.map{ TitlableModelFilteringStrategy(filteringPredicate: $0) }
    }

}

...

struct TitlableModelFilteringStrategy {

    private let filteringPredicate: String
    init(filteringPredicate: String?) {
        self.filteringPredicate = filteringPredicate ?? ""
    }

    func shouldInclude(item: Titlable) -> Bool {
        return filteringPredicate.isEmpty ? true : item.title.localizedCaseInsensitiveContains(filteringPredicate)
    }

    func equals(to another: TitlableModelFilteringStrategy) -> Bool {
        return filteringPredicate == another.filteringPredicate
    }

}

...

protocol Titlable {

    var title: String { get }

}
于 2017-12-07T12:24:23.127 回答