RxSwift中多节tableview的ViewModel输入和输出
我正在实现一个屏幕,它有一个多部分的tableview和一个submit按钮 1.TableView a。第一部分-静态数据(带金额文本输入的单行) b。第二部分-动态数据(多行,带有组和单选按钮,与每个组关联以供选择) 2.提交按钮 通过单选按钮选择金额文本和银行时,按钮启用 以下是Tableview数据源、ViewModel和ViewController的代码RxSwift中多节tableview的ViewModel输入和输出,swift,mvvm,transformation,rx-swift,Swift,Mvvm,Transformation,Rx Swift,我正在实现一个屏幕,它有一个多部分的tableview和一个submit按钮 1.TableView a。第一部分-静态数据(带金额文本输入的单行) b。第二部分-动态数据(多行,带有组和单选按钮,与每个组关联以供选择) 2.提交按钮 通过单选按钮选择金额文本和银行时,按钮启用 以下是Tableview数据源、ViewModel和ViewController的代码 enum PaymentDetailsSections { case amountDetail
enum PaymentDetailsSections {
case amountDetailsSection(items: [RowItems])
case vpaListSection(title: String,items: [RowItems])
}
enum RowItems {
case linkedVPAs(info:String)
case paymentInfo
}
extension PaymentDetailsSections: SectionModelType {
typealias Item = RowItems
var items: [RowItems] {
switch self {
case .amountDetailsSection(items: let items):
return items.map { $0 }
case .vpaListSection(title: _, items: let items):
return items.map { $0 }
}
}
init(original: PaymentDetailsSections, items: [Item]) {
switch original {
case .amountDetailsSection(items: _):
self = .amountDetailsSection(items: items)
case let .vpaListSection(title, _):
self = .vpaListSection(title: title, items: items)
}
}
}
extension PaymentDetailsSections {
var title: String {
switch self {
case .vpaListSection(title: let title, items: _):
return title
case .amountDetailsSection:
return ""
}
}
}
class PaymentViewModel {
Struct Input{
let tableviewFirstSectionTextFieldInput: Observable<String>
let tableviewSecondSectionSelectAnyBank: Observable<BankSelection>
let submitButtonOutSideTableView: Observable<Void>
}
Struct Output{
let results: Observable<Any>
}
let sections:[PaymentDetailsSections]
var likedAccountsRowItems = [RowItems]()
init(_service:Service) {
let vpas = service.linkedVPAs()
for account in vpas {
self.likedAccountsRowItems.append(RowItems.linkedVPAs(info:account))
}
self.sections = [.amountDetailsSection(items: [.paymentInfo]),
.vpaListSection(title:"Transfer From", items:likedAccountsRowItems)]
}
}
class PaymentController{
override func viewDidLoad() {
super.viewDidLoad()
viewModel = PaymentViewModel()
paymentListView.register(UINib(nibName:String(describing: SendMoneyAmountsDetailsCell.self), bundle:nil), forCellReuseIdentifier:String(describing: SendMoneyAmountsDetailsCell.self))
paymentListView.register(UINib(nibName:String(describing: SendMoneyVPAListCell.self), bundle:nil), forCellReuseIdentifier:String(describing: SendMoneyVPAListCell.self))
Observable.just(viewModel.sections)
.bind(to: paymentListView.rx.items(dataSource: self.datasource())).disposed(by: rx.disposeBag)
paymentListView.rx.setDelegate(self).disposed(by: rx.disposeBag)
}
func datasource() -> RxTableViewSectionedReloadDataSource<PaymentDetailsSections> {
return RxTableViewSectionedReloadDataSource<PaymentDetailsSections>(
configureCell: { dataSource, table, idxPath, _ in
switch dataSource[idxPath] {
case .paymentInfo:
if let cell = table.dequeueReusableCell(withIdentifier:String(describing:SendMoneyAmountsDetailsCell.self), for: idxPath) as? SendMoneyAmountsDetailsCell {
return cell
}
case .linkedVPAs(_):
if let cell = table.dequeueReusableCell(withIdentifier:String(describing: SendMoneyVPAListCell.self), for: idxPath) as? SendMoneyVPAListCell {
return cell
}
}
return UITableViewCell()
},
titleForHeaderInSection: { dataSource, index in
let section = dataSource[index]
return section.title
}
)
}
}
枚举付款明细选项{
案例数量详情部分(项目:[行项目])
案例部分(标题:字符串,项:[RowItems])
}
枚举行项目{
案例LinkedVPA(信息:字符串)
案例支付信息
}
延期付款明细部分:部分模型类型{
typealias项目=行项目
变量项:[行项]{
切换自身{
case.amountDetails部分(项:let项):
return items.map{$0}
case.vpaListSection(标题:\项:let项):
return items.map{$0}
}
}
初始(原件:付款明细部分,项目:[项目]){
交换原稿{
case.amountDetails部分(项目):
self=.amountDetailsSection(项:项)
案例说明第节(标题):
self=.vpaListSection(标题:标题,项目:项目)
}
}
}
延期付款明细部分{
变量标题:字符串{
切换自身{
case.vpaListSection(标题:let title,项目:u2;):
返回标题
案例.数量详情部分:
返回“”
}
}
}
类PaymentViewModel{
结构输入{
让tableviewFirstSectionTextFieldInput:可观察
让TableViewSecondSection选择任意银行:可观察
让submitButtonOutSideTableView:可观察
}
结构输出{
结果:可观察
}
let部分:[付款明细部分]
var likedAccountsRowItems=[RowItems]()
init(_服务:服务){
设vpas=service.linkedVPAs()
用于vpas中的帐户{
self.likedAccountsRowItems.append(RowItems.LinkedVPA(信息:帐户))
}
self.sections=[.amountdetails部分(项目:[.paymentInfo]),
.vpaListSection(标题:“转移自”,项目:likedAccountsRowItems)]
}
}
类付费控制器{
重写func viewDidLoad(){
super.viewDidLoad()
viewModel=PaymentViewModel()
register(UINib(nibName:String(描述:SendMoneyAmountsDetailsCell.self)、bundle:nil)、forCellReuseIdentifier:String(描述:SendMoneyAmountsDetailsCell.self))
paymentListView.register(UINib(nibName:String(描述:SendMoneyVPAListCell.self)、bundle:nil)、forCellReuseIdentifier:String(描述:SendMoneyVPAListCell.self))
可观察。仅(viewModel.sections)
.bind(到:paymentListView.rx.items(数据源:self.dataSource()).disposed(由:rx.disposeBag)
paymentListView.rx.setDelegate(self).disposed(作者:rx.disposeBag)
}
func datasource()->RxTableViewSectionedReloadDataSource{
返回RxTableViewSectionedReloadDataSource(
configureCell:{dataSource,table,idxPath,uu中
开关数据源[idxPath]{
案例.付款信息:
如果let cell=table.dequeueReusableCell(带标识符:String(描述:SendMoneyAmountsDetailsCell.self),for:idxPath)为?SendMoneyAmountsDetailsCell{
返回单元
}
案例.LinkedVPA(u2;):
如果let cell=table.dequeueReusableCell(带标识符:String(描述:SendMoneyVPAListCell.self),for:idxPath)为?SendMoneyVPAListCell{
返回单元
}
}
返回UITableViewCell()
},
titleForHeaderInSection:{dataSource,中的索引
let section=数据源[索引]
返回节.标题
}
)
}
}
我找不到任何使用ViewModel中的绑定从ViewController输入并进行输出转换的解决方案。我真的非常感谢任何帮助,并感谢任何提前作出贡献的人
Subject
s的使用有两个原因,一是当您将非接收代码转换为接收代码时,二是当您需要在观察对象存在之前绑定观察者时。这是后一种情况的一个例子
class PaymentViewModel {
...
func output(for input: Input) -> Output {
// put logic here.
}
}
class PaymentController: UIViewController {
...
func bind() {
let input = PaymentViewModel.Input(
tableviewFirstSectionTextFieldInput: textFieldInputSubject.asObservable(),
tableviewSecondSectionSelectAnyBank: bankSelectionSubject.asObservable(),
submitButtonOutSideTableView: submitButton.rx.tap.asObservable()
)
let output = viewModel.output(for: input)
output.buttonEnabled
.bind(to: submitButton.rx.isEnabled)
.disposed(by: disposeBag)
}
let textFieldInputSubject = PublishSubject<String>()
let bankSelectionSubject = PublishSubject<BankSelection>()
...
}
class PaymentViewModel{
...
func输出(对于输入:输入)->输出{
//把逻辑放在这里。
}
}
类PaymentController:UIViewController{
...
func bind(){
让输入=PaymentViewModel.input(
tableviewFirstSectionTextFieldInput:textFieldInputSubject.asObservable(),
TableView第二部分选择任意银行:银行选择Subject.asObservable(),
submitButtonOutSideTableView:submitButton.rx.tap.asObservable()
)
让输出=viewModel.output(for:input)
output.buttonEnabled
.bind(到:submitButton.rx.isEnabled)
.处置(由:处置人)
}
让textFieldInputSubject=PublishSubject()
让bankSelectionSubject=PublishSubject()