【发布时间】:2020-02-21 20:10:08
【问题描述】:
我正在尝试在 Swift 中进入 MVVM,我想知道如何处理 MVVM 中子视图中的事件,以及这些事件如何沿视图/视图模型链向上传播。我现在说的是纯 Swift(没有 SwiftRx 等)。
示例
假设我有一个TableViewController 和一个TableViewModel。视图模型包含一个对象数组并为每个对象创建一个TableCellViewModel,因为每个单元格代表这些对象之一。 TableViewController 从其模型和每个单元格的视图模型中获取要显示的行数,因此它可以将其传递给单元格。
然后我们有一个TableCell,每个单元格都有一个TableCellViewModel。 TableCell 查询其模型以获取面向用户的字符串等内容。
现在假设TableCell 也有一个删除按钮,用于删除该行。我想知道如何处理:通常,单元格会将按钮按下转发到其视图模型,但这不是我们需要它的地方 - 我们最终需要了解TableViewController 或 TableViewModel 中的按钮按下,因此我们可以从表格视图中删除该行。
所以问题是:
按钮事件如何从 MVVM 中的视图链中的 TableCell 向上获取?
代码
根据 cmets 的要求,示例中的代码:
class TableViewController: UIViewController, UITableViewDataSource {
var viewModel: TableViewModel = TableViewModel()
// setup and such
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.viewModel.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableCell
cell.viewModel = self.viewModel.cellViewModel(at: indexPath.item)
return cell
}
}
class TableViewModel {
// setup, get data from somewhere, ...
var count: Int {
return self.modelObjects.count
}
func cellViewModel(at index: Int) -> TableCellViewModel {
let modelObject = self.modelObjects[index]
let cellViewModel = TableCellViewModel(modelObject: modelObject)
return cellViewModel
}
}
class TableCell {
var viewModel: TableCellViewModel!
// setup UI, do what a cell does
func viewModelChanged() {
self.titleLabel.text = self.viewModel.title()
}
func deleteButtonPressed(_ sender: UIButton) {
// Oh, what to do, what to do?
}
}
class TableCellViewModel {
private var modelObject: ModelObject
init(modelObject: ModelObject) {
self.modelObject = modelObject
}
func title() -> String {
return self.modelObject.title
}
}
【问题讨论】:
-
我每天都会遇到的有趣问题。我有质量差的解决方案,如果你愿意,稍后再写。
-
你能展示你的tableview数据源方法吗?
-
这只是一个超级简单的例子,但我添加了一些代码来更好地说明这个例子
-
@BlackWolf 我使用
cellViewModel作为数据存储和预处理器。所有用户操作都使用委托模式发送到viewController。
标签: ios swift user-interface mvvm