如何将 RxDataSource 与 SearchBar 一起使用?
How to use RxDataSource with SearchBar?
我精通 RxSwift,在使用 RxDataSource 时,SearchBar 委托对我不起作用,他,
我看不到错误。没有 RxDataSource 一切正常,在其他屏幕上我没有问题。
告诉我,用新鲜的眼光,错在哪里?为什么过滤器没有发生?
private var defaultCategories: [Groups]!
var groupsCoreData = BehaviorRelay<[Groups]>(value: [])
override func viewDidLoad() {
super.viewDidLoad()
searchBarRx()
tableViewRx()
}
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Groups>>(
configureCell: { (_, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "addNewWordsToGroup")!
cell.textLabel?.text = element.title
return cell
},
titleForHeaderInSection: { dataSource, sectionIndex in
return dataSource[sectionIndex].model
}
)
private func tableViewRx() {
let dataSource = self.dataSource
let items = [
SectionModel(model: "Пример", items: self.defaultCategories
.filter { [=10=].titleCategories == "Тест1"}),
SectionModel(model: "Пример2", items: self.defaultCategories
.filter { [=10=].titleCategories == "Тест2" })
]
Observable.just(items)
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
tableView
.rx
.modelSelected(Groups.self)
.subscribe(onNext: { [weak self] data in
}
.disposed(by: disposeBag)
}
private func searchBarRx() {
searchBar
.rx
.text
.orEmpty
.debounce(.microseconds(200), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.subscribe { [unowned self] query in
self.searchBar.showsCancelButton = query.element!.isEmpty
self.defaultCategories = query.element!.isEmpty ?
self.defaultCategories :
self.defaultCategories
.filter({ [=10=].title?.range(of: query.element!, options: .anchored) != nil
})
}
.disposed(by: disposeBag)
}
query - 显示输入的字符,但没有结果。
P.S。数组不为空
关键是您不要替换数据源。 Rx 是一种功能范例,因此不需要替换。相反,你必须事先勾勒出你的不变量。像这样:
final class ViewController: UIViewController {
var tableView: UITableView!
var searchBar: UISearchBar!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let initialItems = [
SectionModel(model: "Пример", items: [Groups(title: "Group1", titleCategories: "Тест1")]),
SectionModel(model: "Пример2", items: [Groups(title: "Group2", titleCategories: "Тест2")])
]
let searchTerm = searchBar.rx.text.orEmpty
.debounce(.microseconds(200), scheduler: MainScheduler.instance)
.distinctUntilChanged()
Observable.combineLatest(Observable.just(initialItems), searchTerm)
.map { filteredSectionModels(sectionModels: [=10=].0, filter: [=10=].1) }
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}
func filteredSectionModels(sectionModels: [SectionModel<String, Groups>], filter: String) -> [SectionModel<String, Groups>] {
guard !filter.isEmpty else { return sectionModels }
return sectionModels.map {
SectionModel(model: [=10=].model, items: [=10=].items.filter { [=10=].title?.range(of: filter, options: .anchored) != nil
})
}
}
private let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Groups>>(
configureCell: { (_, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "addNewWordsToGroup")!
cell.textLabel?.text = element.title
return cell
},
titleForHeaderInSection: { dataSource, sectionIndex in
return dataSource[sectionIndex].model
}
)
请特别注意我是如何将包含所有项目的 Observable 与跟踪当前搜索过滤器的 Observable 结合起来的。然后我只将实际应该显示的项目发送到 table 视图。
我精通 RxSwift,在使用 RxDataSource 时,SearchBar 委托对我不起作用,他, 我看不到错误。没有 RxDataSource 一切正常,在其他屏幕上我没有问题。 告诉我,用新鲜的眼光,错在哪里?为什么过滤器没有发生?
private var defaultCategories: [Groups]!
var groupsCoreData = BehaviorRelay<[Groups]>(value: [])
override func viewDidLoad() {
super.viewDidLoad()
searchBarRx()
tableViewRx()
}
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Groups>>(
configureCell: { (_, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "addNewWordsToGroup")!
cell.textLabel?.text = element.title
return cell
},
titleForHeaderInSection: { dataSource, sectionIndex in
return dataSource[sectionIndex].model
}
)
private func tableViewRx() {
let dataSource = self.dataSource
let items = [
SectionModel(model: "Пример", items: self.defaultCategories
.filter { [=10=].titleCategories == "Тест1"}),
SectionModel(model: "Пример2", items: self.defaultCategories
.filter { [=10=].titleCategories == "Тест2" })
]
Observable.just(items)
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
tableView
.rx
.modelSelected(Groups.self)
.subscribe(onNext: { [weak self] data in
}
.disposed(by: disposeBag)
}
private func searchBarRx() {
searchBar
.rx
.text
.orEmpty
.debounce(.microseconds(200), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.subscribe { [unowned self] query in
self.searchBar.showsCancelButton = query.element!.isEmpty
self.defaultCategories = query.element!.isEmpty ?
self.defaultCategories :
self.defaultCategories
.filter({ [=10=].title?.range(of: query.element!, options: .anchored) != nil
})
}
.disposed(by: disposeBag)
}
query - 显示输入的字符,但没有结果。 P.S。数组不为空
关键是您不要替换数据源。 Rx 是一种功能范例,因此不需要替换。相反,你必须事先勾勒出你的不变量。像这样:
final class ViewController: UIViewController {
var tableView: UITableView!
var searchBar: UISearchBar!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let initialItems = [
SectionModel(model: "Пример", items: [Groups(title: "Group1", titleCategories: "Тест1")]),
SectionModel(model: "Пример2", items: [Groups(title: "Group2", titleCategories: "Тест2")])
]
let searchTerm = searchBar.rx.text.orEmpty
.debounce(.microseconds(200), scheduler: MainScheduler.instance)
.distinctUntilChanged()
Observable.combineLatest(Observable.just(initialItems), searchTerm)
.map { filteredSectionModels(sectionModels: [=10=].0, filter: [=10=].1) }
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
}
func filteredSectionModels(sectionModels: [SectionModel<String, Groups>], filter: String) -> [SectionModel<String, Groups>] {
guard !filter.isEmpty else { return sectionModels }
return sectionModels.map {
SectionModel(model: [=10=].model, items: [=10=].items.filter { [=10=].title?.range(of: filter, options: .anchored) != nil
})
}
}
private let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Groups>>(
configureCell: { (_, tv, indexPath, element) in
let cell = tv.dequeueReusableCell(withIdentifier: "addNewWordsToGroup")!
cell.textLabel?.text = element.title
return cell
},
titleForHeaderInSection: { dataSource, sectionIndex in
return dataSource[sectionIndex].model
}
)
请特别注意我是如何将包含所有项目的 Observable 与跟踪当前搜索过滤器的 Observable 结合起来的。然后我只将实际应该显示的项目发送到 table 视图。