UICollectionView and MVVM

10

我正在尝试了解如何使用MVVM来开发可重用的UICollectionViewController

假设你为每种UICollectionViewCell类型创建一个视图模型。

struct CollectionTestCellViewModel {
    let name: String
    let surname: String

    var identifier: String {
        return CollectionTestCell.identifier
    }

    var size: CGSize?
}

细胞:

class CollectionTestCell: UICollectionViewCell {
    @IBOutlet weak var surnameLabel: UILabel!
    @IBOutlet weak var nameLabel: UILabel!

    func configure(with viewModel: CollectionTestCellViewModel) {
        surnameLabel.text = viewModel.surname
        nameLabel.text = viewModel.name
    }
}

在视图控制器中,我有类似下面的代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let viewModel = sections[indexPath.section][indexPath.row]
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: viewModel.identifier, for: indexPath)
    configure(view: cell, with: viewModel)
    return cell
}

到目前为止没有问题。 但现在考虑一下这个UICollectionViewDelegateFlowLayout的方法:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let viewModel = sections[indexPath.section][indexPath.row]
    return viewModel.size ?? UICollectionViewFlowLayoutAutomaticSize
}

问题是我在视图模型中有布局信息(单元格的大小)。这使我可以在我的视图控制器中放置布局委托方法,但我不知道这是否违反了MVVM模式。

最后的问题是:我应该在视图模型中放什么(例如一个单元格)?将布局数据放在视图模型中是否“允许”?

谢谢

1个回答

2
在 MVVM 中,视图(View)仅包含视觉元素。我们只做像布局、动画、初始化 UI 组件等这样的事情。在视图(View)和模型(Model)之间有一个特殊的层,称为视图模型(ViewModel)。
视图模型(ViewModel)提供一组接口,每个接口代表视图(View)中的一个 UI 组件。我们使用一种称为“绑定”的技术将 UI 组件连接到视图模型(ViewModel)接口上。因此,在 MVVM 中,我们不直接操作视图(View),而是在视图模型(ViewModel)中处理业务逻辑,从而使视图自动相应变化。
我们将类似将 Date 转换为 String 这样的展示性内容写入视图模型(ViewModel),而不是视图(View)中。
因此,可以编写更简单的测试来测试展示逻辑,而无需了解视图(View)的实现细节。 欲了解更多关于 iOS 中的 MVVM,请阅读本文

1
我认为这个句子有歧义:“ViewModel提供了一组接口,每个接口代表View中的一个UI组件”这种表示方式可以包括UI元素的大小、颜色、字体等吗? - alfogrillo
@drakon 我们在 ViewModel 中创建具有大小、颜色等属性的属性。然后在 ViewController(我们在 MVVM 中的 View)中创建一个 ViewModel 的实例变量,并从中获取值。 - Eugene Karambirov
如果我的回答对您有帮助,请不要忘记将其标记为答案。 - Eugene Karambirov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接