【发布时间】:2020-09-27 07:40:58
【问题描述】:
我正在努力应对以下挑战。我使用包含开关的自定义单元格创建了表格视图。我只想打开一个开关,例如,发射后我打开第三个开关,然后我打开第七个开关,因此第三个开关关闭,依此类推。我对单元使用 rx + 协议,并且一直不明白如何确定切换哪个开关。以前我打算使用过滤器或映射在 dataSource 数组中查找哪个开关打开并以某种方式处理这个问题,但现在我搞砸了。我不确定不使用表视图委托方法是否可行。非常感谢,希望有人能解释我错在哪里。
// CellViewModel 实现
import Foundation
import RxSwift
protocol ViewModelProtocol {
var bag:DisposeBag {get set}
func dispose()
}
class ViewModel:ViewModelProtocol {
var bag = DisposeBag()
func dispose() {
self.bag = DisposeBag()
}
}
protocol CellViewModelProtocol:ViewModelProtocol {
var isSwitchOn:BehaviorSubject<Bool> {get set}
}
class CellVM:ViewModel, CellViewModelProtocol {
var isSwitchOn: BehaviorSubject<BooleanLiteralType> = BehaviorSubject(value: false)
let internalBag = DisposeBag()
override init() {
}
}
//我的Cell实现
import UIKit
import RxSwift
import RxCocoa
class Cell:UITableViewCell {
static let identifier = "cell"
@IBOutlet weak var stateSwitch:UISwitch!
var vm:CellViewModelProtocol? {
didSet {
oldValue?.dispose()
self.bindUI()
}
}
var currentTag:Int?
var bag = DisposeBag()
override func awakeFromNib() {
super.awakeFromNib()
self.bindUI()
}
override func prepareForReuse() {
super.prepareForReuse()
self.bag = DisposeBag()
}
private func bindUI() {
guard let vm = self.vm else { return }
self.stateSwitch.rx.controlEvent(.valueChanged).withLatestFrom(self.stateSwitch.rx.value).observeOn(MainScheduler.asyncInstance).bind(to: vm.isSwitchOn).disposed(by: vm.bag)
}
}
//TableViewController实现
import UIKit
import RxSwift
import RxCocoa
class TableViewController: UITableViewController {
private var dataSource:[CellViewModelProtocol] = []
var vm = TableViewControllerVM()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 70
self.tableView.rowHeight = UITableView.automaticDimension
self.bindUI()
}
private func bindUI() {
vm.dataSource.observeOn(MainScheduler.asyncInstance).bind { [weak self] (dataSource) in
self?.dataSource = dataSource
self?.tableView.reloadData()
}.disposed(by: vm.bag)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataSource.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Cell.identifier, for: indexPath) as! Cell
if cell.vm == nil {
cell.vm = CellVM()
}
return cell
}
}
class TableViewControllerVM:ViewModel {
var dataSource:BehaviorSubject<[CellViewModelProtocol]> = BehaviorSubject(value: [])
let internalBag = DisposeBag()
override init() {
super.init()
dataSource.onNext(createDataSourceOf(size: 7))
self.handleState()
}
private func createDataSourceOf(size:Int) -> [CellViewModelProtocol] {
var arr:[CellViewModelProtocol] = []
for _ in 0..<size {
let cell = CellVM()
arr.append(cell)
}
return arr
}
private func handleState() {
}
}
【问题讨论】:
-
查看this 对相同问题的回答,只需使用 SwiftUI 和 Combine。您应该可以使用相同的想法,只需将其转换为 RxSwift 和 UIKit。
-
非常感谢@DávidPásztor!
标签: ios swift functional-programming switch-statement rx-swift