当关注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)
}
答案 0 :(得分:1)
我遵循的一般经验法则是如果我必须将UIKit导入视图模型,我做错了。 (我说一般是因为在视图模型中可能存在从UIKit需要某些东西的合法用例。)
正如一些评论中所提到的,视图模型旨在将某些项目暴露给您的视图控制器。您应该避免在视图模型中直接执行与UI相关的操作。这可能会影响视图模型的可重用性,并且不允许独立于UI代码进行测试。
在您的情况下,您似乎将视图模型用作表视图委托。如果您创建了视图控制器的扩展并在那里实现了委托协议,那么从mvvm的角度来看可能会更好。您可以在视图控制器类声明下面执行此操作,如下所示:
class ViewController {
...
}
extension ViewController: UITableViewDelegate {
...
}
如果需要在委托函数中操作视图状态,可以在视图模型中公开变量或函数,并在委托函数中调用它。
答案 1 :(得分:0)
ViewModel 是纯 NSObject 。 查看表示为 UIView 或 UIViewController 对象。您的 uicollectionView 应该在您的UIViewController中,ViewModel附加它。 ViewModel 隐藏所有异步网络代码,模型更改等。
find