我试图了解如何使用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模式。
最后一个问题是:我应该在视图模型(例如单元格)中放置什么? “允许”将布局数据放在视图模型中?
谢谢
在MVVM中,View仅包含可视元素。我们只做布局,动画,初始化UI组件等事情。在视图和模型之间有一个称为ViewModel的特殊层。
ViewModel提供了一组接口,每个接口代表View中的UI组件。我们使用称为“绑定”的技术将连接UI组件连接到ViewModel接口。因此,在MVVM中,我们不直接触摸View,我们在ViewModel中处理业务逻辑,因此View会相应地更改自身。
我们编写表达性的东西,比如在ViewModel中将Date
转换为String
而不是View。
因此,可以在不知道View的实现的情况下为表示逻辑编写更简单的测试。
要了解有关iOS read this article中MVVM的更多信息。