iOS中的MVVM模式

时间:2018-01-22 00:43:12

标签: ios swift mvvm

当关注MVVM时,ViewModel如何获得对View的引用?

例如,UITableViewController的VM符合协议UITableViewDelegate,在-didSelectRowAtIndexPath方法中,VM如何调用navigationController.pushViewController等方法?

一个天真的解决方案是在初始化ViewModel时传入视图控制器。还有其他更好的方法来实现这个目标吗?

e.g。在viewmodel.swift中:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
   let vc = UIStoryboard.Main.instantiateViewController(withIdentifier: "postDetailsVC") as! PQPostDetailsViewController
   let cell = collectionView.cellForItem(at: indexPath) as! PQProductCollectionViewCell
   vc.featureImage = cell.productImageView.image

   // Cannot call the following since ViewModel is not a UIViewController
   self.navigationController?.pushViewController(vc, animated: true)
}

2 个答案:

答案 0 :(得分:1)

我遵循的一般经验法则是如果我必须将UIKit导入视图模型,我做错了。 (我说一般是因为在视图模型中可能存在从UIKit需要某些东西的合法用例。)

正如一些评论中所提到的,视图模型旨在将某些项目暴露给您的视图控制器。您应该避免在视图模型中直接执行与UI相关的操作。这可能会影响视图模型的可重用性,并且不允许独立于UI代码进行测试。

在您的情况下,您似乎将视图模型用作表视图委托。如果您创建了视图控制器的扩展并在那里实现了委托协议,那么从mvvm的角度来看可能会更好。您可以在视图控制器类声明下面执行此操作,如下所示:

class ViewController {
...
}

extension ViewController: UITableViewDelegate {
...
}

如果需要在委托函数中操作视图状态,可以在视图模型中公开变量或函数,并在委托函数中调用它。

答案 1 :(得分:0)

ViewModel 是纯 NSObject 查看表示为 UIView UIViewController 对象。您的 uicollectionView 应该在您的UIViewController中,ViewModel附加它。 ViewModel 隐藏所有异步网络代码,模型更改等。

find