Я использую RxSwift для отображения списка лиц в моем табличном представлении, и мое табличное представление состоит из двух разделов: первый - это старые запросы, а второй - все люди.теперь я не знаю, как мне фильтровать людей, когда пользователи вводят имя в текстовом поле UISearchBar.
Это моя модель Person:
struct PersonModel {
let name: String
let family:String
let isHistory:Bool
}
Это моя ContactsViewModel
struct SectionOfPersons {
var header: String
var items: [Item]
}
extension SectionOfPersons: SectionModelType {
typealias Item = PersonModel
init(original: SectionOfPersons, items: [SectionOfPersons.Item]) {
self = original
self.items = items
}
}
class ContactsViewModel {
let items = PublishSubject<[SectionOfPersons]>()
func fetchData(){
var subItems : [SectionOfPersons] = []
subItems.append( SectionOfPersons(header: "History", items: [
SectionOfPersons.Item(name:"Michelle", family:"Obama", isHistory:true ),
SectionOfPersons.Item(name:"Joanna", family:"Gaines", isHistory:true )
]))
subItems.append( SectionOfPersons(header: "All", items: [
SectionOfPersons.Item(name:"Michelle", family:"Obama", isHistory:false ),
SectionOfPersons.Item(name:"James", family:"Patterson", isHistory:false ),
SectionOfPersons.Item(name:"Stephen", family:"King", isHistory:false ),
SectionOfPersons.Item(name:"Joanna", family:"Gaines", isHistory:false )
]))
self.items.onNext( subItems )
}
}
и это мой ContactsViewController:
class ContactsViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
private lazy var dataSource = RxTableViewSectionedReloadDataSource<SectionOfPersons>(configureCell: configureCell, titleForHeaderInSection: titleForHeaderInSection)
private lazy var configureCell: RxTableViewSectionedReloadDataSource<SectionOfPersons>.ConfigureCell = { [weak self] (dataSource, tableView, indexPath, contact) in
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ContactTableViewCell", for: indexPath) as? ContactTableViewCell else { return UITableViewCell() }
cell.contact = contact
return cell
}
private lazy var titleForHeaderInSection: RxTableViewSectionedReloadDataSource<SectionOfPersons>.TitleForHeaderInSection = { [weak self] (dataSource, indexPath) in
return dataSource.sectionModels[indexPath].header
}
private let viewModel = ContactsViewModel()
private let disposeBag = DisposeBag()
var showContacts = PublishSubject<[SectionOfPersons]>()
var allContacts = PublishSubject<[SectionOfPersons]>()
override func viewDidLoad() {
super.viewDidLoad()
bindViewModel()
viewModel.fetchData()
}
func bindViewModel(){
tableView.backgroundColor = .clear
tableView.register(UINib(nibName: "ContactTableViewCell", bundle: nil), forCellReuseIdentifier: "ContactTableViewCell")
tableView.rx.setDelegate(self).disposed(by: disposeBag)
viewModel.items.bind(to: allContacts).disposed(by: disposeBag)
viewModel.items.bind(to: showContacts).disposed(by: disposeBag)
showContacts.bind(to: tableView.rx.items(dataSource: dataSource)).disposed(by: disposeBag)
searchBar
.rx.text
.orEmpty
.debounce(0.5, scheduler: MainScheduler.instance)
.distinctUntilChanged()
.filter { !$0.isEmpty }
.subscribe(onNext: { [unowned self] query in
////// if my datasource was simple string I cand do this
self.showContacts = self.allContacts.filter { $0.first?.hasPrefix(query) } // if datasource was simple array string, but what about complex custome object?!
})
.addDisposableTo(disposeBag)
}
}
Спасибо за ваш ответ.