Reputation: 1960
Recently started writing code in Swift using reactive programming. Reactive programming is little confusing concept, anyway i want to implement tableview with expand and collapse concept using reactive programming. I tried in my own way, i am able to write code for implementing normal, section tableview and here they provided examples also, but for expand and collapse tableview i did not find any example. Can any one please provide the solution for this.
Upvotes: 0
Views: 1737
Reputation: 2748
I Assume you're familiar with "combineLatest". This answer is not really "clean" but will somehow give the idea of how to implement it:
first define an array:
var expansions = [Variable<Bool>].init(repeating: Variable<Bool>(true), count: 2)
I only had 2 sections in my case, If you have unknown number of sections you have to use [Int: Variable<Bool>]
to map each section into this dictionary.
now define a method for getting the expansion:
func expansion(for section: Int) -> Variable<Bool> {
/* if using [Int: Variable<Bool>]
if expansions[section] == nil {
expansions[section = Variable<Bool>(false)
}*/
return expansions[section]
}
now filter your items using Observable.combineLatest
and expansion(for: _)
And in tableView delegate:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// next line just dequeues a UITableViewHeaderFooterView subclass.
let view = tableView.dequeueReusableHeaderFooter(forSection: section) as ExpandableHeader
view.titleLabel.text = dataSource[section].model.title
view.isExpanded = expansions[section].value // just a variable to update header's UI
view.expandButton.rx.controlEvent(.touchUpInside)
.bind { [weak self, weak view = view] in
guard let strongSelf = self else { return }
strongSelf.expansions[section].value = !strongSelf.expansions[section].value
view?.isExpanded = strongSelf.expansions[section].value // because dataSource will not reload this view itself unless it gets dequeued.
}
.disposed(by: view.disposeBag)
return view
}
I'm disposing this subscription with view.disposeBag
not the one i'm using in this viewController. because view.disposeBag
will get renewed in prepareForReuse()
every-time, and will remove all previous subscribers. (not using such method, will not cause memory-leak, but it will cause ViewController to consume lots of resources and of-course unwanted behavior)
Upvotes: 0