也使用 UISearchController 时的 RxSwift UITableView 绑定
Posted
技术标签:
【中文标题】也使用 UISearchController 时的 RxSwift UITableView 绑定【英文标题】:RxSwift UITableView binding when also using a UISearchController 【发布时间】:2017-11-26 19:24:15 【问题描述】:在我的视图控制器中,我有一个与 UITableView 关联的 UISearchController。所以我所有的普通表视图数据源方法都是旧的
if isSearching
// use filteredTableData array
else
// use SharedModel.shared.participants
我不清楚如何使用 RxCocoa 来实现它,因为我是 Rx 的新手。
【问题讨论】:
【参考方案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
【讨论】:
【参考方案2】:我通过为Observable
声明一个装饰器和为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
【讨论】:
以上是关于也使用 UISearchController 时的 RxSwift UITableView 绑定的主要内容,如果未能解决你的问题,请参考以下文章
UISearchController UISearchBar 背景
从 UISearchController 搜索栏快速删除黑色边框