ios - 在 Swift 的 MVVM 中处理 subview 中的事件

标签 ios swift user-interface mvvm

我正尝试在 Swift 中使用 MVVM,我想知道如何在 MVVM 中处理 subview 中的事件,以及这些事件如何沿着 View / View 模型链传播。我现在谈论的是纯 Swift(没有 SwiftRx 等)。

示例

假设我有一个带有 TableViewModelTableViewController。 View 模型包含一个对象数组,并为每个对象创建一个 TableCellViewModel,因为每个单元格代表这些对象之一。 TableViewController 从其模型中获取要显示的行数以及每个单元格的 View 模型,因此它可以将其传递给单元格。

然后我们有一个 TableCell,每个单元格都有一个 TableCellViewModelTableCell 查询其模型以获取诸如面向用户的字符串等内容。

现在假设 TableCell 也有一个删除按钮,用于删除该行。我想知道如何处理:通常,单元会将按钮按下转发到它的 View 模型,但这不是我们需要它的地方 - 我们最终需要知道 TableViewController 中的按钮按下> 或 TableViewModel,这样我们就可以从 TableView 中删除该行。

那么问题是:
在 MVVM 的 View 链中,按钮事件如何从 TableCell 向上获取?

代码

按照评论中的要求,示例代码:

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
    }

}

最佳答案

TableViewModel 是真实的来源,因此所有全局操作都应在其中执行。按下按钮完全是 UI 操作,viewModel 不应该直接处理它。

所以,现在我们知道两个事实:

  1. TableViewModel 应该从数组中删除单元格,然后 viewController 应该处理删除动画过程;
  2. 不应在子 viewModel 中处理按钮按下。

根据这个你可以通过以下方式实现:

  1. 将按钮按下事件向上传递给 viewController(使用回调或委托(delegate)模式);
  2. 调用TableViewModel方法删除特定单元格:

    viewModel.deleteCell(at: indexPath)

  3. 妥善处理viewController中的删除动画。

关于ios - 在 Swift 的 MVVM 中处理 subview 中的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58559098/

相关文章:

c - 构建 Win32 GUI 代码

ios - 从 firestore 下载一系列文档

objective-c - IOS 在 PDF 中嵌入字体

ios - 如何使用按钮处理 UITableViewCell 中的多点触控?

ios - 在 Xcode 9 Beta 5 中向 NSMutableArray 添加元素时出错

java - 但为什么 swing 不绘制我的组件?

java - JPanel 添加到容器时只显示一个组件

ios - 使用 PhotoLibrary 作为源时 UIImagePickerController 崩溃

Swift 测试一个类型是否与另一个类型兼容

swift - 允许我的客户查询我的后端是否不好?